[英]Postgres `gin_trgm_ops` index not being used
我正在嘗試使用pg_trgm
擴展來加快 Postgres中的某些文本匹配:
CREATE TABLE test3 (id bigint, key text, value text);
insert into test3 values (1, 'first 1', 'second 3');
insert into test3 values (2, 'first 1', 'second 2');
insert into test3 values (2, 'first 2', 'second 3');
insert into test3 values (3, 'first 1', 'second 2');
insert into test3 values (3, 'first 1', 'second 3');
insert into test3 values (4, 'first 2', 'second 3');
insert into test3 values (4, 'first 2', 'second 3');
insert into test3 values (4, 'first 1', 'second 2');
insert into test3 values (4, 'first 1', 'second 2');
-- repeat the above 1,000,000x times, to have more rows for benchmarking
insert into test3(id, key, value) select id, key, value from test3 cross join generate_series(1, 1000000);
現在我用ILIKE
查詢該表:
select count(*) from test3 where key = 'first 1' and value ilike '%nd 3%';
Time: 918.265 ms
為了查看索引是否可以加快速度,我在key
和value
列上都添加了pg_trgm
:
CREATE extension if not exists pg_trgm;
CREATE INDEX test3_key_trgm_idx ON test3 USING gin (key gin_trgm_ops);
CREATE INDEX test3_value_trgm_idx ON test3 USING gin (value gin_trgm_ops);
但是查詢仍然需要相同的時間,並且EXPLAIN ANALYZE
顯示根本沒有使用索引:
explain analyze select count(*) from test3 where key = 'first 1' and value ilike '%nd 3%';
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=126905.14..126905.15 rows=1 width=8) (actual time=1017.666..1017.667 rows=1 loops=1)
-> Gather (cost=126904.93..126905.14 rows=2 width=8) (actual time=1017.505..1018.778 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=125904.93..125904.94 rows=1 width=8) (actual time=1010.862..1010.862 rows=1 loops=3)
-> Parallel Seq Scan on test3 (cost=0.00..122427.06 rows=1391148 width=0) (actual time=0.041..973.550 rows=666667 loops=3)
Filter: ((value ~~* '%nd 3%'::text) AND (key = 'first 1'::text))
Rows Removed by Filter: 2333336
Planning Time: 0.266 ms
Execution Time: 1018.814 ms
Time: 1049.413 ms (00:01.049)
注意順序掃描。 是什么賦予了?
沒關系,我發現了問題。
查詢計划者比我的玩具測試集還聰明。 看到大多數行都與查詢匹配,因此進行了順序掃描。
如果我嘗試使用ilike '%nd 0%'
,則沒有行匹配,並且EXPLAIN ANALYZE正確報告Bitmap Index Scan on test3_value_trgm_idx
。
因此,以這種方式規范化原始JSONB是可行的。 但是,我還將嘗試查找和比較另一種方法,即通過TEXT
使用正則表達式,以避免必須創建和維護另一個表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.