PG:查詢計劃器與random_page_cost
查詢計劃器與random_page_cost
本周小貼士比較奇怪,基于我們今天遇到的一個問題。將簡訊的鏈接存儲到一個簡單數(shù)據(jù)庫中:
CREATE TABLE links (
uid CHAR(60) PRIMARY KEY,
data TEXT,
timestamp INT
)
CREATE INDEX idx_trgm ON links USING GIN (data gin_trgm_ops)
當然,這個設計比較爛。但僅供內(nèi)部使用,我只是一個粗略的想法原型。數(shù)據(jù)是一個包含json(I know, I know...)的文本,以同樣可怕的方式檢查鏈接的存在:
SELECT * FROM links WHERE data ILIKE '%whatever we want%' LIMIT 1;
在低容量下運行很好,但查詢時間偶爾會超過300ms,很好奇這是為啥?
執(zhí)行EXPLAIN ANALYZE后,發(fā)現(xiàn)PG根本沒使用GIN索引,而是使用了全表掃描。但是如果去掉LMIT 1,查詢將使用索引,執(zhí)行只需要5ms。為什么PG會忽略索引?
PG的查詢規(guī)劃器并不是真正基于人們做一些荒唐的事情。比如使用ILIKE進行全表掃描,關心的是走索引快還是全表掃描快。變量random_page_cost用于決定使用索引的代價是否值得,或者和seq_page_cost合作使用。
這種情況下,索引掃描是值得的,但是查詢規(guī)劃器不同意。因為看起來很簡單的LIMIT 1,只找到一個結果就可以停止。并繼續(xù)進行全表掃描。
SET random_page_cost = 1;
EXPLAIN ANALYZE SELECT * ... LIMIT 1;
[see the index being used]
SET random_page_cost = DEFAULT;
EXPLAIN ANALYZE SELECT * ... LIMIT 1;
[see the index NOT being used]
除了明顯的“修復那個糟糕的模式”,看看PG會做什么,如果覺得索引掃描和順序掃描比代價低。因此如果最終得到的查詢使用索引,那么有必要嘗試一下,通過EXPLAIN ANALYZE分析。

請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
推薦專題
-
10 月之暗面,絕地反擊
- 1 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達AI統(tǒng)治的開始
- 2 北電數(shù)智主辦酒仙橋論壇,探索AI產(chǎn)業(yè)發(fā)展新路徑
- 3 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 4 “AI寒武紀”爆發(fā)至今,五類新物種登上歷史舞臺
- 5 國產(chǎn)智駕迎戰(zhàn)特斯拉FSD,AI含量差幾何?
- 6 光計算迎來商業(yè)化突破,但落地仍需時間
- 7 東陽光:2024年扭虧、一季度凈利大增,液冷疊加具身智能打開成長空間
- 8 地平線自動駕駛方案解讀
- 9 封殺AI“照騙”,“淘寶們”終于不忍了?
- 10 優(yōu)必選:營收大增主靠小件,虧損繼續(xù)又逢關稅,能否乘機器人東風翻身?