Postgresql

postgres:SELECT 字元串的索引,例如 ‘%foo%’;

  • May 28, 2017

我有一個昂貴的、定期的 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 個字節(fillfactorbtree 索引的預設值為 90%),因此您不妨好好利用索引並提供幫助其他查詢。如果您有任何其他可能使用相同部分索引的查詢?

如果您放置的內容最多可達 8 個字節(如一列或兩int4列),則索引將保持完全相同的大小和性能,但提供更多可能的案例。如果(其中一個)列涉及更新,則您需要支付一些額外的維護費用。不過,如果您有任何有用的東西,請使用它。JOIN在/ WHEREorORDER 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;

表達索引

引用自:https://dba.stackexchange.com/questions/76045