简体   繁体   English

sql替代

[英]sql Like alternate

Is there any other solution available to use instead of Like to match starts with? 是否有其他可用的解决方案代替“喜欢匹配”开头?

here is my query to match starts with using 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)

which is very expansive because it does sequence scan instead of index scan. 这非常可扩展,因为它执行顺序扫描而不是索引扫描。 due to nature of like it can not use index on provided column. 由于喜欢的性质,它不能在提供的列上使用索引。 index of column is simple as: 列的索引很简单,如下所示:

"i_call_id" btree (call_id)

Is there any special class of index which can help like to improve speed, or any other way to achieve same without using like? 是否有任何特殊的索引类可以帮助您提高速度,或者通过其他任何方式不使用like即可达到相同的速度?

Used Table script is: 使用的表脚本是:

              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)

This case of LIKE index use (or lack thereof) is described in the doc : 文档中描述了这种使用LIKE索引(或缺少索引)的情况:

In short you should create the index as 简而言之,您应该将索引创建为

create index i_call_id on completedcalls(call_id varchar_pattern_ops);

But read the page linked above for the caveats. 但是请阅读上面链接的页面以了解警告。

LIKE statements can still be used with b-tree indexes , assuming that there is no leading wildcard: 假设没有前导通配符, LIKE语句仍可以与b树索引一起使用

The optimizer can also use a B-tree index for queries involving the pattern matching operators LIKE and ~ if the pattern is a constant and is anchored to the beginning of the string — for example, col LIKE 'foo%' or col ~ '^foo' , but not col LIKE '%bar' . 优化器还可以使用B树索引进行涉及模式匹配运算符LIKE和〜的查询,如果模式是一个常数并且锚定在字符串的开头,例如col LIKE 'foo%'col ~ '^foo' ,而不是col LIKE '%bar'

If your index isn't being used, then it is for a reason other than the usage of LIKE shown here... 如果未使用您的索引,则其原因不是此处显示的LIKE用法。

While I'm not sure if it would help the performance, have you looked into using regular expressions? 虽然我不确定这是否会对性能有所帮助,但您是否研究过使用正则表达式? You could use the caret ^ to return the records located at the beginning of the string. 您可以使用插入号^返回位于字符串开头的记录。

Maybe something like this: 也许是这样的:

select * 
from completedcalls 
where call_id ~ '^GWYA4NvSLzoIcvA7RAtmn_a9IelwOQeH@209.44.103.3';

LIKE is able to use an index on a condition with a trailing % . LIKE可以在后跟%的条件下使用索引。

It's possible that the optimizer thinks a full scan would be better than an index scan, as the latter required additional table lookups for other columns and record visibility scope. 优化器可能认为完全扫描会比索引扫描更好,因为索引扫描需要对其他列和记录可见性范围进行额外的表查找。

From the looks of it, you should probably split up that call_id column into separate columns for each of the components. 从外观上看,您可能应该将该call_id列拆分为每个组件的单独列。 For example, you could add additional columns with indices for what looks like an ID and an IP address in your example, make those indices and then select on those. 例如,您可以在示例中添加带有索引的其他列,这些索引看起来像ID和IP地址,然后创建这些索引,然后在这些索引上进行选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM