2015-06-15 98 views
4

我有一個查詢在`LIKE:varname ||上使用索引'%'`在火鳥

SELECT DISTINCT FKDOCUMENT 
FROM PNTM_DOCUMENTS_FT_INDEX 
WHERE WORD LIKE 'sometext%' 

計劃SORT((PNTM_DOCUMENTS_FT_INDEX INDEX(IX_PNTM_DOCUMENTS_FT_INDEX)))

和它的作品沒關係。

,但是當我嘗試使用連接字符串與LIKE,火鳥不使用indicies

SELECT DISTINCT FKDOCUMENT 
FROM PNTM_DOCUMENTS_FT_INDEX 
WHERE WORD LIKE 'sometext' || '%' 

計劃SORT((PNTM_DOCUMENTS_FT_INDEX自然科學))

如何迫使它使用指示?

+2

如果通配符總是結束,那麼使用'STARTING'而不是'LIKE',即'where word starting'foo'' - 這應該更加優化器友好。 – ain

+0

@你是最好的 – tjomamokrenko

+0

您的標題與您的問題的內容不符。你在標題中使用了一個參數,還是在第二個例子中使用了純字符串連接(或者兩者都有相同的效果?) –

回答

5

簡短的回答,正如ain已經評論過的,如果你不需要類似的模式,但總是想做一個前綴搜索,則使用STARTING [WITH]而不是LIKE。所以:

WHERE WORD STARTING WITH 'sometext' -- No %! 

WHERE WORD STARTING WITH :param 

據我所知,這正是火鳥確實有LIKE 'sometext%'。這將在可用時使用索引,並且您不需要爲類似圖案符號的存在而轉義它。缺點是你不能使用像圖案符號。

現在,爲什麼火鳥當您使用

WHERE WORD LIKE :param || '%' -- (or LIKE :param) for that matter 

WHERE WORD LIKE 'sometext' || '%' 

第一種情況不使用索引很容易解釋:語句的準備與執行分開進行。 Firebird需要考慮到參數值以_或更糟 - %開頭的可能性,並且它不能爲此使用索引。

至於第二種情況,它應該可以優化到相當於LIKE 'sometext%',但火鳥可能認爲任何不是一個普通的文字不可優化。對於這個特定的例子,可以確定它應該是可優化的,但這是一個非常特殊的例外(通常一個不像這樣連接文字,大多數情況下一個或多個'黑'框如列,函數,case語句等)參與)。