Kam*_*nek 5 sql postgresql json full-text-search sql-like
我有一个people以body列为jsonb类型的表。
Table "public.people"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
-----------------+-----------------------------+-----------+----------+--------------------+----------+--------------+-------------
id | uuid | | not null | uuid_generate_v4() | plain | |
body | jsonb | | not null | | extended | |
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
"idx_name" gin ((body ->> 'name'::text) gin_trgm_ops)
Run Code Online (Sandbox Code Playgroud)
我的索引如下所示:
CREATE INDEX idx_name ON people USING gin ((body ->> 'name') gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)
但是,当我这样做时:
EXPLAIN ANALYZE SELECT * FROM "people" WHERE ((body ->> 'name') ILIKE '%asd%') LIMIT 40 OFFSET 0;
Run Code Online (Sandbox Code Playgroud)
我懂了:
Limit (cost=0.00..33.58 rows=40 width=104) (actual time=100.037..4066.964 rows=11 loops=1)
-> Seq Scan on people (cost=0.00..2636.90 rows=3141 width=104) (actual time=99.980..4066.782 rows=11 loops=1)
Filter: ((body ->> 'name'::text) ~~* '%asd%'::text)
Rows Removed by Filter: 78516
Planning time: 0.716 ms
Execution time: 4067.038 ms
Run Code Online (Sandbox Code Playgroud)
为什么那里不使用索引?
更新
为了避免与上面提到的运算符混淆,我将引用 http://www.sai.msu.su/~megera/oddmuse/index.cgi/Gin
Gin 内置了对一维数组的支持(例如,integer[]、text[]),但不支持 NULL 元素。可以进行以下操作:
- 包含: value_array @> query_array
- 重叠:值数组&&查询数组
- 包含: value_array <@ query_array
如果你想利用 GIN 的优点,请使用@>,而不是LIKE运算符
另外,请看看欧文对密切问题的更好回答