2010-02-11 89 views
0

如果你想相關性,同時將結果按相關性進行排序的全文查詢的通用格式是:替代MySQL的全文搜索語法

SELECT name, MATCH(name) AGAINST('Bob') AS relevance FROM users WHERE MATCH(name) AGAINST('Bob')

作爲一個開發者,我總是喜歡讓我的代碼幹(不要重複自己)。有什麼理由不編寫查詢爲:

SELECT name, MATCH(name) AGAINST('Bob') AS relevance FROM users HAVING relevance > 0 ORDER BY relevance DESC

這似乎返回相同的結果,但我應該擔心的ORDER BY導致查詢要慢一些?這些查詢是否相同?

指定MATCH()兩次不會降低MySQL手冊中提到的性能。

Natural Language Full-Text Searches

爲了實現這個結果,你應該 指定MATCH()兩次:一次是在 SELECT列表,一次在WHERE 條款。這不會引起額外的開銷,因爲MySQL優化器 注意到兩個MATCH()調用是 相同並且僅調用一次全文 搜索代碼。

回答

1

不幸的是,根據MySQL SELECT documentation,「HAVING子句幾乎是最後一個應用,就在項目發送給客戶端之前,沒有優化。」

區別在於第一個查詢將使用全文索引來計算相關性只有行中有'Bob'name。第二個查詢將計算所有行的相關性,然後丟棄其中的大部分(可能在對整個表進行排序後)。因此,第二個查詢顯着較慢。即使你把ORDER BY子句到第一查詢時,它仍然會比使用具有速度快:「請不要使用具有的項目應該是在WHERE子句中」

SELECT name, MATCH(name) AGAINST('Bob') AS relevance 
FROM users 
WHERE MATCH(name) AGAINST('Bob') 
ORDER BY relevance DESC 

一般情況下,

+0

我試過使用WHERE相關性> 0但是然後我得到這個錯誤'where子句'中的未知列'相關性' – ejunker 2010-02-11 18:46:18

+0

是的。 WHERE子句在SELECT表達式之前計算*,因此它不能爲這些表達式使用任何別名。 HAVING子句在執行後執行,因此可以使用這些別名;然而,只有WHERE子句可以讓MySQL優化無用的計算。 在這種情況下,DRY或速度:請選擇。 – eswald 2010-02-11 19:06:10