1

是否有任何其他解决方案可供使用而不是 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)
4

5 回答 5

3

文档中描述了这种LIKE索引使用(或缺少)的情况:

简而言之,您应该将索引创建为

create index i_call_id on completedcalls(call_id varchar_pattern_ops);

但是请阅读上面链接的页面以了解警告。

于 2013-01-15T20:48:53.183 回答
2

LIKE假设没有前导通配符,语句仍然可以与 b-tree 索引一起使用:

优化器还可以对涉及模式匹配运算符的查询使用 B-tree 索引,LIKE如果模式是常量并且锚定到字符串的开头 - 例如,col LIKE 'foo%'col ~ '^foo',但不是col LIKE '%bar'

如果您的索引没有被使用,那么它的原因不是LIKE这里显示的用法......

于 2013-01-15T20:42:23.877 回答
1

虽然我不确定它是否有助于提高性能,但您是否考虑过使用正则表达式?您可以使用插入符号^返回位于字符串开头的记录。

也许是这样的:

select * 
from completedcalls 
where call_id ~ '^GWYA4NvSLzoIcvA7RAtmn_a9IelwOQeH@209.44.103.3';
于 2013-01-15T20:42:14.877 回答
1

LIKE能够在带有尾随的条件上使用索引%

优化器可能认为完全扫描比索引扫描更好,因为后者需要对其他列和记录可见性范围进行额外的表查找。

于 2013-01-15T20:42:21.690 回答
0

从外观上看,您可能应该将该 call_id 列拆分为每个组件的单独列。例如,您可以为示例中的 ID 和 IP 地址添加带有索引的附加列,创建这些索引,然后在这些索引上进行选择。

于 2013-01-15T20:42:51.360 回答