JSONB ILIKE索引

时间:2017-11-29 13:28:57

标签: sql json postgresql full-text-search sql-like

我有一个peoplebody列作为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)

我的索引如下:

CREATE INDEX idx_name ON people USING gin ((body ->> 'name') gin_trgm_ops);

然而,当我这样做时:

EXPLAIN ANALYZE SELECT * FROM "people" WHERE ((body ->> 'name') ILIKE '%asd%') LIMIT 40 OFFSET 0;

我明白了:

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

为什么没有在那里使用索引?

1 个答案:

答案 0 :(得分:2)

更新

为了避免与上面提到的运营商混淆,我会引用 http://www.sai.msu.su/~megera/oddmuse/index.cgi/Gin

  

Gin带有对一维数组的内置支持(例如。   integer [],text []),但不支持NULL元素。下列   操作可用:

     
      
  • 包含:value_array @> query_array
  •   
  • 重叠:value_array&& query_array
  •   
  • 包含:value_array< @ query_array
  •   

如果您想使用GIN的优势,请使用@>,而不是LIKE运算符

另外,请查看much better Erwins answer on close question