2010-08-12 82 views
2

我在使用MySQL的全文搜索並按順序返回結果時遇到問題。我必須使用布爾全文搜索,它不會按相關性順序返回結果。但是,我需要這些結果的相關性順序。如果我試圖在查詢的末尾添加一個order by子句,則查詢結果爲使用filesort,這會使查詢非常慢(比沒有慢1000多倍)。我不確定可以做什麼。通過使用布爾全文搜索的相關性排序

這裏是我的查詢:

SELECT g.id, MATCH(g.searchable_name) AGAINST ('test*' IN BOOLEAN MODE) AS relevance 
FROM games g 
WHERE MATCH(g.searchable_name) AGAINST ('test*' IN BOOLEAN MODE) 
ORDER BY relevance DESC 
LIMIT 0, 31 

在此先感謝。

+1

'相關性'是一個計算列 - 你不能對其應用索引;看到「使用filesort」就像你會得到的一樣好。爲什麼'分數'值不適用於排序? – 2010-08-12 21:25:38

+0

分數值?你能解釋一下你的意思嗎? (我是新的全文搜索。) – 2010-08-12 21:27:28

+1

http://stackoverflow.com/questions/3471733/ordering-fulltext-searches-on-relevance-and-other-fields – 2010-08-12 21:32:10

回答

0

首先,你應該考慮到IN BOOLEAN MODEdoes not return a score,而是返回二進制(1 =發現,0 =未找到):

mysql>SELECT 
     topic_id, 
     MATCH(topic_text) AGAINST('+tuning' IN BOOLEAN MODE) AS binary 
    FROM 
     topics_search 
    LIMIT 10 
+----------+----------+ 
| topic_id | binary | 
+----------+----------+ 
| 2  | 0  | 
| 4  | 0  | 
| 5  | 0  | 
| 6  | 1  | 
| 7  | 0  | 
| 8  | 0  | 
| 11  | 0  | 
| 12  | 0  | 
| 13  | 0  | 
| 14  | 0  | 
+----------+----------+ 
10 rows in set (9 ms) 

只有自然的全文搜索能夠產生一個分數(在IN NATURAL LANGUAGE MODE修改沒有給出,因爲它是默認模式):

mysql>SELECT SQL_NO_CACHE 
     topic_id, 
     MATCH(topic_text) AGAINST('tuning') AS score 
    FROM 
     topics_search 
    WHERE 
     host_id = 1 
    ORDER BY 
     score DESC 
    LIMIT 10 
+--------------------+--------------------+ 
| topic_id   | score    | 
+--------------------+--------------------+ 
| 153257    | 5.161948204040527 | 
| 17925    | 4.781417369842529 | 
| 66459    | 4.648380279541016 | 
| 373176    | 4.570812702178955 | 
| 117173    | 4.55166482925415 | 
| 167016    | 4.462575912475586 | 
| 183286    | 4.4519267082214355 | 
| 366132    | 4.348565101623535 | 
| 95502    | 4.293642520904541 | 
| 29615    | 4.178250789642334 | 
+--------------------+--------------------+ 
10 rows in set (478 ms) 

旁註:難以置信緩慢的,因爲score不能有一個索引。

所以你需要自然搜索按分數排序。但自然搜索不支持*通配符等運營商。現在我們有困難了,因爲BOOLEAN中搜索tunin*並且使用密鑰tuninNATURAL中執行並行搜索沒有用,因爲沒有文本會包含該部分詞。

mysql>SELECT SQL_NO_CACHE 
     topic_id, 
     MATCH(topic_text) AGAINST('tunin') AS score 
    FROM 
     topics_search 
    WHERE 
     MATCH(topic_text) AGAINST('tunin*' IN BOOLEAN MODE) 
    AND 
     MATCH(topic_text) AGAINST('tunin') > 0 
    ORDER BY 
     score DESC 
    LIMIT 10 
Empty set (170 ms) 

結論
這是不可能的通配符搜索和按相關性排序結果。

除非您找到一種方法來獲取全文索引中被通配符搜索命中的所有單詞,並在第二個查詢中使用它們,或者根據LIKE構建自己的分數,並計算得到的結果中的單詞數量行。有趣的是打開a new question

+0

哪個'ENGINE'顯示結果? – 2017-02-14 02:19:38