pg中我们可以使用pg_trgm插件来进行模糊查询,但是这个插件有个缺陷在于:不支持单、双字节的文本,因为它是将对象进行切词,每3个字节为一组进行切割,所以单、双字节的就无法覆盖到。
对于单、双字的模糊查询我们可以自定义一个切词函数,然后使用gin索引来进行索引扫描。
例子:
创建自定义切词函数:
bill=# create or replace function split_12(text) returns text[] as $$
bill$# declare
bill$# res text[];
bill$# begin
bill$# select regexp_split_to_array($1, '') into res;
bill$# for i in 1..length($1)-1
bill$# loop
bill$# res := array_append(res, substring($1, i, 2));
bill$# end loop;
bill$# return res;
bill$# end;
bill$# $$ language plpgsql strict immutable;
CREATE FUNCTION
建表:
bill=# create table t1(id int,info text);
CREATE TABLE
bill=# insert into t1 select random()*100,md5(random()::text) from generate_series(1,100000);
INSERT 0 100000
创建索引:
bill=# create index idx_t1 on t1 using gin(split_12(info));
CREATE INDEX
查询:
双字测试可以使用索引了。
bill=# explain select * from t1 where split_12(info) @> array['ab'];
QUERY PLAN
--------------------------------------------------------------------------
Bitmap Heap Scan on t1 (cost=95.89..3913.73 rows=11367 width=37)
Recheck Cond: (split_12(info) @> '{ab}'::text[])
-> Bitmap Index Scan on idx_t1 (cost=0.00..93.05 rows=11367 width=0)
Index Cond: (split_12(info) @> '{ab}'::text[])
(4 rows)