首先我创建表和索引,这里是定义:
CREATE TABLE boxes(id SERIAL PRIMARY KEY, text text, name character varying(255) COLLATE pg_catalog."C.UTF-8")
development=# CREATE INDEX boxes_name_idx ON boxes USING btree (name COLLATE pg_catalog."C.UTF-8" varchar_pattern_ops);
development=# \d boxes
Table "public.boxes"
Column | Type | Modifiers
--------+------------------------+----------------------------------------------------
id | integer | not null default nextval('boxes_id_seq'::regclass)
text | text |
name | character varying(255) | collate C.UTF-8
Indexes:
"boxes_pkey" PRIMARY KEY, btree (id)
"boxes_name_idx" btree (name varchar_pattern_ops)
其次,将10003项插入表中,并解释查询。但它变化缓慢:
development=# EXPLAIN ANALYZE SELECT name FROM boxes WHERE name ILIKE '%商品%';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on boxes (cost=626.93..1019.21 rows=3 width=87) (actual time=2.356..48.937 rows=3 loops=1)
Filter: ((name)::text ~~* '%商品%'::text)
Rows Removed by Filter: 10100
Heap Blocks: exact=266
-> Bitmap Index Scan on boxes_name_idx (cost=0.00..626.92 rows=10103 width=0) (actual time=1.910..1.910 rows=10103 loops=1)
Planning time: 0.509 ms
Execution time: 48.973 ms
(7 rows)
development=# EXPLAIN ANALYZE SELECT name FROM boxes WHERE name COLLATE pg_catalog."C.UTF-8" ILIKE '%商品%';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on boxes (cost=626.93..1019.21 rows=3 width=87) (actual time=2.358..49.039 rows=3 loops=1)
Filter: ((name)::text ~~* '%商品%'::text)
Rows Removed by Filter: 10100
Heap Blocks: exact=266
-> Bitmap Index Scan on boxes_name_idx (cost=0.00..626.92 rows=10103 width=0) (actual time=1.896..1.896 rows=10103 loops=1)
Planning time: 0.506 ms
Execution time: 49.073 ms
(7 rows)
development=# SELECT name FROM boxes WHERE name ILIKE '%商品%';
name
-----------
商品标题3
商品标题
商品标题2
(3 rows)
development=# SELECT count(id) FROM boxes;
count
-------
10103
(1 row)
development=# SHOW LC_COLLATE;
lc_collate
-------------
en_HK.UTF-8
(1 row)
我们可以看到,索引没有被Filter使用。
我的PostgreSQL版本是9.5.1
答案 0 :(得分:3)
documentation在这一点上非常明确:
优化器也可以使用B树索引进行涉及的查询 模式匹配运算符LIKE和〜如果模式是常量和 锚定在字符串的开头 - 例如
col LIKE 'foo%' or col ~ '^foo'
,但不是col LIKE '%bar'
。
您的模式以通配符开头。因此,它不使用索引。
Postgres有GIN,GIST和n-gram索引来支持全文支持。