是否有其他可用的解决方案而非Like匹配开头?
这是我的查询匹配开头使用like。
explain analyze select * from completedcalls where call_id like 'GWYA4NvSLzoIcvA7RAtmn_a9IelwOQeH@209.44.103.3%';
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Seq Scan on completedcalls (cost=0.00..52659.96 rows=112 width=228) (actual time=1.541..249.857 rows=2 loops=1)
Filter: ((call_id)::text ~~ 'GWYA4NvSLzoIcvA7RAtmn_a9IelwOQeH@209.44.103.3%'::text)
Total runtime: 249.893 ms
(3 rows)
这是非常广泛的,因为它执行序列扫描而不是索引扫描。由于它的性质,它不能使用提供列上的索引。列的索引很简单:
"i_call_id" btree (call_id)
是否有任何特殊的索引类可以帮助提高速度,或者在不使用的情况下以任何其他方式实现相同的目标?
使用过的表脚本是:
Table "public.completedcalls"
Column | Type | Modifiers
---------------+--------------------------+--------------
call_id | character varying(128) |
sip_code | integer |
duration | integer |
setup_time | timestamp with time zone | not null
authname | character varying(30) |
src_sig_ip | character varying(20) |
dst_sig_ip | character varying(20) |
cld | character varying(22) |
cli | character varying(22) |
Indexes:
"i_call_id" btree (call_id)
"i_dst_sig_ip" btree (dst_sig_ip)
答案 0 :(得分:3)
doc中描述了LIKE
索引使用(或缺少索引)的情况:
简而言之,您应该将索引创建为
create index i_call_id on completedcalls(call_id varchar_pattern_ops);
但请阅读上面链接的页面以获取警告。
答案 1 :(得分:2)
LIKE
statements can still be used with b-tree indexes,假设没有前导通配符:
优化器也可以使用B树索引进行涉及的查询 模式匹配运算符
LIKE
和〜如果模式是常量和 锚定在字符串的开头 - 例如col LIKE 'foo%'
或col ~ '^foo'
,但不是col LIKE '%bar'
。
如果你的索引没有被使用,那么这是因为这里显示的LIKE
的使用不是......
答案 2 :(得分:1)
虽然我不确定它是否有助于提高性能,但您是否考虑过使用正则表达式?您可以使用插入符^
返回位于字符串开头的记录。
也许是这样的:
select *
from completedcalls
where call_id ~ '^GWYA4NvSLzoIcvA7RAtmn_a9IelwOQeH@209.44.103.3';
答案 3 :(得分:1)
LIKE
能够在条件为%
的情况下使用索引。
优化器可能认为完整扫描比索引扫描更好,因为后者需要对其他列进行额外的表查找并记录可见范围。
答案 4 :(得分:0)
从它的外观来看,您应该将该call_id列拆分为每个组件的单独列。例如,您可以添加带有索引的其他列,以查看示例中的ID和IP地址,制作这些索引然后选择这些索引。