首页 > > > PostgreSQL LIKE的那些事
'abc' LIKE 'abc' true'abc' LIKE 'a%' true'abc' LIKE '_b_' true'abc' LIKE 'c' false
select tablename from pg_tables where tablename like 'tbl!_%'ESCAPE '!';'abc' ~~ '_b_' true'abc' ~~ '_B_' false'abc' ~~* '_B_' true
select 'abc' ^@ 'ab' trueselect 'abc' ^@ 'b' falseselect starts_with('abc','a') trueselect starts_with('abc','b') false
'abc' SIMILAR TO 'abc' true'abc' SIMILAR TO 'a' false'abc' SIMILAR TO '%(b|d)%' true'abc' SIMILAR TO '(b|c)%' false
substring('foobar' , '%#"o_b#"%' , '#') oobsubstring('foobar' , '#"o_b#"%' , '#') NULLsubstring('foobar' from '%#"o_b#"%' for '#') oobsubstring('foobar' from '#"o_b#"%' for '#') NULL
'abc' ~ 'abc' true'abc' ~ '^a' true'abc' ~ '(b|d)' true'abc' ~ '^(b|c)' false
substring('foobar' from 'o.b') oobsubstring('foobar' from 'o(.)b') o
| 函数 | 作用 | 举例 | 举例输出 |
| regexp_replace | 使用指定的字符替换匹配到的表达式 | regexp_replace(‘foobarbaz’, ‘b(…)’, ‘X\1Y’, ‘g’) | fooXarYXazY |
| regexp_match | 以数组形态输出匹配到的表达式 | regexp_match(‘foobarbequebaz’, ‘(bar)(beque)’) | {bar,beque} |
| regexp_matches | 以多行输出返回多个匹配到的表达式 | regexp_matches(‘foobarbequebazilbarfbonk’, ‘(b[b]+)(b[b]+)’,‘g’) | {bar,beque},{bazil,barf} |
| regexp_split_to_table | 使用正则表达式切割行,每个匹配一行 | regexp_split_to_table(‘the quick brown’, ‘\s+’) | the,quick,brown三行 |
| regexp_split_to_array | 使用正则表达式切割行为数组 | regexp_split_to_array(‘the quick brown’, ‘\s+’) | {the,quick,brown} |
以上,就是语法层面的一些讨论了,接下来,让我们看看实际使用的时候,具体的优化如何处理。
| 参数名称 | 参数说明 | 默认值 |
| max_parallel_workers | 全局最多可以启动的worker上限 | 8 |
| max_parallel_workers_per_gather | 每个执行节点最大的可用worker数量 | 2 |
| min_parallel_index_scan_size | 索引查询时候,单个worker最小的工作量 | 64 |
| min_parallel_table_scan_size | 表数据查询的时候,单个worker最小的工作量 | 1024 |
Table "public.item_test"Column | Type | Collation | Nullable | Default------------+-----------------------------+-----------+----------+---------id | integer | | |name | character varying(512) | | |cover | integer | | |path | text | | |parent | integer | | |library_id | integer | | |version | integer | | |order_id | integer | | |item_type | character varying(128) | | |ctime | timestamp without time zone | | |utime | timestamp without time zone | | |file_type | character varying(128) | | |
mynas=> explain select count(*) from item_test where name like '(C96%';QUERY PLAN-------------------------------------------------------------------------------------Aggregate (cost=10000270364.64..10000270364.65 rows=1 width=8)-> Seq Scan on item_test (cost=10000000000.00..10000270363.23 rows=567 width=0)Filter: (name ~~ '(C96%'::text)mynas=> select count(1) from item_test where name like '(C96%';count-------536(1 row)Time: 745.689 ms
mynas=> create index idx_itemtest on item_test(name varchar_pattern_ops);CREATE INDEXTime: 25311.067 ms (00:25.311)mynas=> explain select count(1) from item_test where name like '(C96%';QUERY PLAN--------------------------------------------------------------------------------------------------Aggregate (cost=85608.37..85608.38 rows=1 width=8)-> Bitmap Heap Scan on item_test (cost=978.63..85526.89 rows=32592 width=0)Filter: ((name)::text ~~ '(C96%'::text)-> Bitmap Index Scan on idx_itemtest (cost=0.00..970.48 rows=32592 width=0)Index Cond: (((name)::text ~>=~ '(C96'::text) AND ((name)::text ~<~ '(C97'::text))(5 rows)mynas=> select count(1) from item_test where name like '(C96%';count-------536(1 row)Time: 4.852 ms
mynas=> select count(1) from item_test where name like '%C96';count-------1(1 row)Time: 989.560 msmynas=> select count(1) from item_test where name like '%C96%';count-------922(1 row)Time: 922.812 ms
mynas=# create index idx_itemtest on item_test(reverse(name) varchar_pattern_ops);CREATE INDEXmynas=> select count(1) from item_test where name like '%C96';count-------1(1 row)Time: 1051.475 ms (00:01.051)mynas=> select count(1) from item_test where reverse(name) like '69C%';count-------1(1 row)Time: 3.034 ms
mynas=> explain select count(1) from item_test where name ilike '(C96%';QUERY PLAN--------------------------------------------------------------------------------------------Aggregate (cost=85522.33..85522.34 rows=1 width=8)-> Bitmap Heap Scan on item_test (cost=970.80..85519.07 rows=1304 width=0)Filter: ((name)::text ~~* '(C96%'::text)-> Bitmap Index Scan on idx_itemtest (cost=0.00..970.48 rows=32592 width=0)Index Cond: (((name)::text ~>=~ '('::text) AND ((name)::text ~<~ ')'::text))mynas=> select count(1) from item_test where name ilike '(C96%';count-------536(1 row)Time: 63.164 ms
mynas=> drop index idx_itemtest;DROP INDEXmynas=> select count(1) from item_test where name ilike '(C96%';count-------536(1 row)Time: 3946.207 ms (00:03.946)
mynas=> create extension pg_trgm;mynas=> create index idx_itemtest on item_test using gist(name gist_trgm_ops);CREATE INDEXmynas=> explain select count(1) from item_test where name like '%C96%';QUERY PLAN------------------------------------------------------------------------------------------Aggregate (cost=218395.90..218395.91 rows=1 width=8)-> Bitmap Heap Scan on item_test (cost=15665.13..217744.06 rows=260737 width=0)Recheck Cond: ((name)::text ~~ '%C96%'::text)-> Bitmap Index Scan on idx_itemtest (cost=0.00..15599.94 rows=260737 width=0)Index Cond: ((name)::text ~~ '%C96%'::text)(5 rows)mynas=> select count(1) from item_test where name like '%C96%';count-------922(1 row)Time: 557.345 msmynas=> drop index idx_itemtest;DROP INDEXmynas=> create index idx_itemtest on item_test using gin(name gin_trgm_ops);CREATE INDEXmynas=> explain select count(1) from item_test where name like '%C96%';QUERY PLAN-----------------------------------------------------------------------------------------Aggregate (cost=205151.49..205151.50 rows=1 width=8)-> Bitmap Heap Scan on item_test (cost=2420.71..204499.64 rows=260737 width=0)Recheck Cond: ((name)::text ~~ '%C96%'::text)-> Bitmap Index Scan on idx_itemtest (cost=0.00..2355.53 rows=260737 width=0)Index Cond: ((name)::text ~~ '%C96%'::text)(5 rows)mynas=> select count(1) from item_test where name like '%C96%';count-------922(1 row)Time: 6.019 ms
mynas=> explain select count(1) from item_test where name like '%C9%';QUERY PLAN--------------------------------------------------------------------------Aggregate (cost=273622.43..273622.45 rows=1 width=8)-> Seq Scan on item_test (cost=0.00..270363.22 rows=1303684 width=0)Filter: ((name)::text ~~ '%C9%'::text)(3 rows)mynas=> select count(1) from item_test where name like '%C9%';count-------10039(1 row)Time: 1033.843 ms (00:01.034)
mynas=> create or replace function split001(text) returns text[] as $$mynas$> declaremynas$> res text[];mynas$> beginmynas$> select regexp_split_to_array($1,'') into res;mynas$> for i in 1..length($1)-1 loopmynas$> res := array_append(res, substring($1,i,2));mynas$> end loop;mynas$> return res;mynas$> end;mynas$> $$ language plpgsql strict immutable;CREATE FUNCTIONmynas=> create index idx_itemtest on item_test using gin(split001(name) );mynas=> explain select count(1) from item_test where split001(name) @> array['C9'];QUERY PLAN---------------------------------------------------------------------------------------Aggregate (cost=93090.33..93090.34 rows=1 width=8)-> Bitmap Heap Scan on item_test (cost=312.59..93008.85 rows=32592 width=0)Recheck Cond: (split001((name)::text) @> '{C9}'::text[])-> Bitmap Index Scan on idx_itemtest (cost=0.00..304.44 rows=32592 width=0)Index Cond: (split001((name)::text) @> '{C9}'::text[])(5 rows)mynas=> select count(1) from item_test where split001(name) @> array['C9'];count-------10039(1 row)Time: 15.190 ms
mynas=> alter table item_test add column tk tsvector;mynas=> update item_test set tk=to_tsvector(name) ;mynas=> create index idx_idx_itemtest on item_test using gin (tk);CREATE INDEXTime: 19366.479 ms (00:19.366)mynas=> explain select count(1) from item_test where tk @@ to_tsquery('%C96%');QUERY PLAN-----------------------------------------------------------------------------------------Aggregate (cost=4545.10..4545.11 rows=1 width=8)-> Bitmap Heap Scan on item_test (cost=32.76..4542.35 rows=1099 width=0)Recheck Cond: (tk @@ to_tsquery('%C96%'::text))-> Bitmap Index Scan on idx_idx_itemtest (cost=0.00..32.49 rows=1099 width=0)Index Cond: (tk @@ to_tsquery('%C96%'::text))(5 rows)mynas=> select count(1) from item_test where tk @@ to_tsquery('C96');count-------786(1 row)Time: 4.172 msmynas=> select count(1) from item_test where name like '%C96%';count-------922(1 row)Time: 1610.243 ms (00:01.610)
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69917105/viewspace-3157886/ ,如需转载,请注明出处,否则将追究法律责任。