2016-09-19 9 views
0

Таблица:users с full 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по убыванию по умолчанию, но здесь мне нужно условие двойной сортировки, поэтому я выбираю столбец.

Поясните Extended:

+----+-------------+-------+----------+------------------+----------+---------+-----+------+----------+-----------------------------+ 
| 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

I думаю так что. Это часто пишется с помощью оговорки 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

К сожалению, ваш запрос не использует индекс * (проверено с объяснением) *. Сканирование строк 86K +. Я думаю, его причина в том, что условие не в WHERE, а после предложения. – Shaharyar

0

Да и нет.

WHERE MATCH... будет выполняться несколько раз, тем самым «отфильтровывая» строки, которые не соответствуют друг другу. Только оставшиеся строки должны будут выполнить команду MATCH второй раз.

HAVING, с другой стороны, должен был бы выполнить MATCH для всех строк (кроме одного с этим uid), построить временную таблицу со всеми этими строками. Только тогда можно было сделать фильтрацию HAVING.

Итак, даже если MATCH выполняется меньше раз в версии HAVING, запрос, вероятно, будет работать быстрее.

Вы do есть FULLTEXT(username), не так ли?

Почему, почему, используйте полнотекстовый запрос против одного слова?

+0

Если я создаю временную таблицу со всеми отфильтрованными строками для применения к ней 'HAVING', не будет ли она такой же, как мой текущий запрос? Или, может быть, я ошибаюсь. Помимо своего минимального примера, я сопоставляю логику с каким-то другим сценарием. – Shaharyar

+0

Это будет по сути то же самое, что и исходный запрос - только медленнее из-за явного создания таблицы tmp. –

+0

Это означает, что я могу сказать, что мой текущий запрос подходит для сценария, и нет способа получить условие WHERE в предложении SELECT? – Shaharyar