我有一个表,该表包含约500,000行,其列的值类似于Brutus, Dreamer of the Wanton Wasteland
。我需要对它们执行不区分大小写的LIKE
查询,但它的执行速度似乎很慢。我尝试使用以下方法建立索引:
create index name_idx on deck (name);
和
create index deck_name_idx on deck (lower(name));
但是无论哪种方式查询都同样缓慢。这是我的查询:
select *
from deck
where lower(deck.name) like '%brutus, dreamer of the%'
order by deck.id desc
limit 20
这是我的解释分析的结果(这是第二个索引,但是两者都同样慢)。
Limit (cost=152534.89..152537.23 rows=20 width=1496) (actual time=627.480..627.490 rows=1 loops=1)
-> Gather Merge (cost=152534.89..152539.56 rows=40 width=1496) (actual time=627.479..627.488 rows=1 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Sort (cost=151534.87..151534.92 rows=20 width=1496) (actual time=611.447..611.447 rows=0 loops=3)
Sort Key: id DESC
Sort Method: quicksort Memory: 25kB
-> Parallel Seq Scan on deck (cost=0.00..151534.44 rows=20 width=1496) (actual time=609.818..611.304 rows=0 loops=3)
Filter: (lower((name)::text) ~~ '%brutus, dreamer of the%'::text)
Rows Removed by Filter: 162210
Planning time: 0.786 ms
Execution time: 656.510 ms
是否有更好的方法来建立此索引?如果需要的话,我可以将该列反规范化为小写版本,但是我不希望这样做,除非它会有所帮助并且没有更好的方法。
答案 0 :(得分:3)
要支持LIKE
开头没有通配符的查询,请使用
CREATE INDEX ON deck (lower(name) varchar_pattern_ops);
要支持开头可以使用通配符的LIKE
搜索,您可以
CREATE EXTENSION pg_trgm;
CREATE INDEX ON deck USING gin (lower(name) gin_trgm_ops);