2013-01-15 14 views
1

是否有任何其他解決方案可用來代替Like來匹配開頭?sql像備用

這裏是我的查詢匹配開始使用like。

explain analyze select * from completedcalls where call_id like '[email protected]%'; 
                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 ~~ '[email protected]%'::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

您可以發佈'CREATE TABLE'腳本嗎? – Quassnoi

+0

只是拋出一個想法:在'call_id'中爲所需字符下標並將它們與字符串進行比較時,性能如何? – woemler

回答

3

LIKE索引使用(或缺乏)此情況下,在doc描述:

總之你應該創建索引作爲

create index i_call_id on completedcalls(call_id varchar_pattern_ops); 

但閱讀上述用於警告鏈接的頁面。

1

雖然我不知道這是否會幫助表現,你看着使用正則表達式?您可以使用插入符號^來返回位於字符串開頭的記錄。

也許是這樣的:

select * 
from completedcalls 
where call_id ~ '^[email protected]'; 
1

LIKE能夠在條件使用索引後帶上%

優化器可能認爲全掃描會比索引掃描更好,因爲後者需要其他列的附加表查找並記錄可見性範圍。

+0

如何提供告訴postgresql使用索引掃描的提示? – sharafjaffri

+0

@sharafjaffri:'PostgreSQL'的創建者主動對象實現提示,否則不行。你認爲你真的需要它嗎?表格中有多少條記錄以及它們中有多少條滿足條件? – Quassnoi

+0

有1041583條記錄和2條記錄滿足這個條件。 – sharafjaffri

2

LIKE statements can still be used with b-tree indexes,假設不存在前通配符:

優化器也可以使用用於涉及 模式匹配運營商LIKE和〜查詢B樹索引,如果圖案是一個常數和 是錨定到字符串的開頭 - 例如,col LIKE 'foo%'col ~ '^foo',但不是col LIKE '%bar'

如果不使用索引,那麼它是不是在這裏顯示LIKE使用其他的理由...

+1

這個問題被標記爲postgresql,所以MySQL手冊不太可能有很大幫助 –

+0

我在call_id的結尾處只使用了一個通配符%,但清楚地表明它使用了Seq Scan並且它在postgresql上也是如此。 – sharafjaffri

+0

@DanielVérité謝謝,當我發佈這個答案時,我沒有看到該標籤...我更新了引用相應的postgresql文檔。 –

0

從外觀上來看,你應該分手了那CALL_ID列爲每個組件分成不同的列。例如,您可以在示例中添加帶有索引的附加列,其內容類似於ID和IP地址,然後製作這些索引,然後選擇這些索引。