sql喜欢alternate

时间:2013-01-15 20:37:45

标签: python sql postgresql indexing sql-like

是否有其他可用的解决方案而非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)

5 个答案:

答案 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地址,制作这些索引然后选择这些索引。