我正在使用postgres 9.6。我将JSONB数据存储在一列中,我将提高一个查询的性能。在我的json数据中,我有name
列,它是文本。我使用以下查询查询此数据。
SELECT "id", "body", "created_at", "updated_at"
FROM "read_models"
WHERE ((body ->> 'name') ILIKE '%asd%')
LIMIT 40 OFFSET 0;
以下是此查询的分析结果:
Limit (cost=0.00..33.58 rows=40 width=72) (actual
time=112.428..4071.757 rows=11 loops=1)
|
| -> Seq Scan on read_models
(cost=0.00..2636.90 rows=3141 width=72) (actual time=112.416..4071.646
rows=11 loops=1) |
| Filter: ((body ->> 'name'::text) ~~* '%asd%'::text)
|
| Rows Removed by Filter: 78516
|
| Planning time: 1.658 ms
|
| Execution time: 4071.847 ms
我为此属性创建了以下索引:
CREATE EXTENSION pg_trgm;
CREATE INDEX idx_name ON read_models USING gin ((body ->> 'name') gin_trgm_ops);
我创建了不同的索引类型,但它始终是相同的结果。查询时间与没有任何索引的情况相同。我看到PG在查询数据时不使用此索引。我看到很多信息如何索引postgres中的文本数据,我不明白为什么它在我的情况下不起作用。谢谢你的帮助。
答案 0 :(得分:2)
问题在于你的条件不是SARGABLE
What makes a SQL statement sargable?
您可以使用LIKE 'ABC%'
的索引,但不能使用LIKE '%ABC%'
检查这些提示,即使对于MySQL,大部分也适用于Postgres MySQL索引TIPS