2011-11-14 41 views
0

我有一個在SQL中定義的函數,用於計算兩個給定字符串之間的Levenshtein距離。SQL語句中的臨時變量

目前我調用此函數的方式類似於下面的一個:

SELECT * FROM movies M WHERE levenshtein (M.title, "Foobar") < 5; 

我想用才能在萊文斯坦距離的升序的結果,但不知道正確的方式做所以。

有沒有辦法做到這一點,還是我必須以不同的方式做到這一點?

回答

2

levenshtein()是一個昂貴的功能。如果表現完全相關,那麼您可能希望避免稱它爲兩次。使用一個子選擇。 (在其他RDBMS中,您可能使用CTE,但MySQL不具備這一點。)

運行測試以查看哪個更好。

SELECT some_col 
FROM (SELECT some_col, levenshtein(title, 'Foobar') AS levi FROM movies) AS m 
WHERE levi < 5 
ORDER BY levi; 

順便說一句,你不想把表的別名在SELECT列表一樣在你的榜樣,是嗎?

+0

對不起,這個錯誤!我修好了它。 謝謝你展示這個! –

0
ORDER BY levenshtein (M.title, "Foobar") 
+0

我在想這件事,但是這樣做不是兩次調用這個函數(它已經很貴了,所以我不認爲我應該調用它兩次)?還是它優化? –

0

我相信你可以只by子句重用的順序功能,像這樣:

SELECT * 
FROM movies M 
WHERE levenshtein (M.title, "Foobar") < 5 
ORDER BY levenshtein (M.title, "Foobar"); 

另一種選擇,是輸出的所有記錄的結果,與另外一列的你的函數調用,到一個臨時表,然後使用相關列上的WHEREORDER BY子句進行選擇。

+0

我一直在想這個,但是這不會調用函數兩次(它已經很昂貴,所以我不認爲我應該調用它兩次)?還是它優化? –

+0

@Kaushik我不完全確定。如果你使用第二種方法(使用臨時表),它只會被調用一次。 –

0

對於尋找類似答案的人來說,我有一些同類問題的實踐經驗。

雖然它工作得很好,有問題...

ORDER BY levenshtein (M.title, "Foobar") 

...並不在於它從測試執行功能的兩倍(對50萬行的表,我不相信它),但查詢使用filesort來執行ORDER BY。正如您可能知道的那樣,將ORDERed列納入WHERE子句中將不再需要filesort。問題在於ORDER的值不是列,並且不像純列引用那樣工作。