2016-09-19 109 views
0

表:usersfull text search索引在列username按相關度排序的全文搜索排序

查詢:

SELECT 
    MATCH (username) AGAINST ('shaharyar' IN NATURAL LANGUAGE MODE) AS `score`, 
    uid, 
    first_name, 
    username, 
    `status`, 
    created 
FROM users 
WHERE 
    MATCH (username) AGAINST ('shaharyar' IN NATURAL LANGUAGE MODE) AND 
    uid <> 164125 -- to prevent self profile search 
ORDER BY 
    score DESC, 
    created DESC 

問題:請問Match條款執行2次?

我知道MySQL的排序由score降序默認,但在這裏我需要這就是爲什麼我選擇列雙排序條件。

解釋擴展:

+----+-------------+-------+----------+------------------+----------+---------+-----+------+----------+-----------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered |   Extra   | 
+----+-------------+-------+----------+------------------+----------+---------+-----+------+----------+-----------------------------+ 
| 1 | SIMPLE  | users | fulltext | PRIMARY,username | username |  0 |  | 1 |  100 | Using where; Using filesort | 
+----+-------------+-------+----------+------------------+----------+---------+-----+------+----------+-----------------------------+ 

關於150K +記錄在表中。

回答

0

認爲所以。這通常是使用having子句寫成的:

SELECT MATCH (username) AGAINST ('shaharyar' IN NATURAL LANGUAGE MODE) AS `score`, 
     uid, first_name, username, `status`, created 
FROM users 
WHERE uid <> 164125 -- to prevent self profile search 
HAVING score > 0 
ORDER BY score DESC, created DESC; 
+0

不幸的是,您的查詢沒有使用索引*(與Explain一起檢查)*。掃描86K +行。我認爲它的原因是條件不在WHERE子句中,而是在子句之後。 – Shaharyar

0

是和否。

WHERE MATCH...將被執行若干次,從而「過濾」出不「匹配」的行。只有剩餘的行需要第二次執行MATCH

HAVING另一方面,將不得不爲所有行執行MATCH(除了具有該uid的行),請使用所有這些行構建臨時表。只有這樣,HAVING才能進行過濾。

因此,即使MATCHHAVING版本中執行次數較少,查詢運行速度可能會更快。

FULLTEXT(username),不是嗎?

爲什麼,爲什麼要對一個單詞使用全文查詢?

+0

如果我創建一個包含所有過濾行的臨時表來對其應用'HAVING',它會不會與我當前的查詢相同?或者可能是我把你的觀點弄錯了。除了它最簡單的例子之外,我將邏輯映射到其他場景。 – Shaharyar

+0

這將基本上與原始查詢相同 - 由於顯式創建tmp表,因此速度較慢。 –

+0

這意味着我可以說我目前的查詢適合該場景,並且沒有辦法在SELECT子句中獲取WHERE條件? – Shaharyar