Postgresql
postgres:SELECT 字元串的索引,例如 ‘%foo%’;
我有一個昂貴的、定期的 PostgreSQL 9.3 查詢,格式如下:
SELECT * from mytable where name NOT LIKE '%foo%';
foo
這裡實際上是一個永遠不會改變的常數。該查詢很昂貴,因為它需要進行表掃描。我希望只有幾行實際匹配查詢,所以我想使用部分索引來加快查詢速度。CREATE INDEX foo_idx ON mytable ((name NOT LIKE '%foo%')) WHERE name NOT LIKE '%foo%';
但是,當我
EXPLAIN
對查詢進行查詢時,它仍然使用順序掃描而不是依賴新索引。 我究竟做錯了什麼?我在語句的括號表達式子句中嘗試了幾種不同的表達式
CREATE INDEX
,但沒有任何幫助:CREATE INDEX foo_idx ON mytable (name) WHERE name NOT LIKE '%foo%'; CREATE INDEX foo_idx ON mytable ((name LIKE '%foo%')) WHERE name NOT LIKE '%foo%';
我也嘗試過刪除
WHERE
索引的子句,但這也無濟於事。
索引應該按原樣工作。正如@jjanes 所指出的,您只需要執行
ANALYZE
. 但是,我建議您修改索引。您定義中的表達式沒有用。CREATE INDEX foo_idx ON intentions ((data LIKE '%foo%')) WHERE data NOT LIKE '%foo%';
表達總是
FALSE
無用的噪音。要麼簡化為稍微便宜一點的等效索引:CREATE INDEX foo_idx ON intentions ((FALSE)) WHERE data NOT LIKE '%foo%';
或者,更好的是,在那裡放一些有用的東西。由於無論如何每個索引條目都會為數據分配
MAXALIGN
(通常為 8 個字節),並且每個索引行的成本是另外 12 個字節(fillfactor
btree 索引的預設值為 90%),因此您不妨好好利用索引並提供幫助其他查詢。如果您有任何其他可能使用相同部分索引的查詢?如果您放置的內容最多可達 8 個字節(如一列或兩
int4
列),則索引將保持完全相同的大小和性能,但提供更多可能的案例。如果(其中一個)列涉及更新,則您需要支付一些額外的維護費用。不過,如果您有任何有用的東西,請使用它。JOIN
在/WHERE
orORDER BY
子句中使用的任何附加列。或啟用僅索引掃描的列:CREATE INDEX foo_idx ON intentions (<useful_column(s)>) WHERE data NOT LIKE '%foo%';
您可以嘗試稍微不同的方法。
CREATE INDEX foo_idx ON mytable (strpos(name,'foo')); SELECT * from mytable where strpos(name,'foo') = 0;