【问题标题】:JSONB ILIKE indexingJSONB ILIKE 索引
【发布时间】:2018-05-13 05:38:09
【问题描述】:

我有一个表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)

我的索引如下:

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

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

【问题讨论】:

  • 你找到答案了吗?我面临同样的问题:JSONB 值中的字符串无法将三元组索引与 ILIKE 一起使用。

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


【解决方案1】:

更新

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

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

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

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

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

【讨论】:

  • 此外,请查看this discussion 上有关非可搜索查询的信息。
  • FTS的问题是我不能在那里模拟%query%
  • 你不需要模拟它 - ilike '%val%' 可以正常工作,它只是不会使用 FTS 索引。我的意思是你问为什么那里没有使用索引?,简短的回答是因为你使用LIKE运算符
  • 我们不使用数组,而是在字符串中搜索。
  • 我正在查看body 中是否存在与name 匹配的特定字符串,而不是body 中是否存在精确的JSON。
猜你喜欢
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
  • 2020-06-01
  • 1970-01-01
  • 2018-05-12
相关资源
最近更新 更多