SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 13.04.2011 20:22:09

YAAP
Завсегдатай
Зарегистрирован: 17.02.2010
Сообщений: 31

Match against. Разделение матчей

Жил был медленный запрос (в таблице 1кк записей) вида

SELECT
SQL_NO_CACHE *, (MATCH (search_keywords) AGAINST(' +(>firstWord <firstWord*) +(>secondWord <secondWord*) +(>thirdWord <thirdWord*)' IN BOOLEAN MODE)) AS Relevance
FROM table WHERE
(MATCH (search_keywords) AGAINST('+(>firstWord <firstWord*) +(>secondWord <secondWord*) +(>thirdWord <thirdWord*)' IN BOOLEAN MODE)) AND
 ...
GROUP BY ...
ORDER BY  ..
LIMIT ....

Запрос такой выполняется 7-9 секунд

Методом проб и ошибок было выявлено, что немного переделанный запрос отрабатывает за 1с, при этом результаты выдает одинаковые
SELECT
SQL_NO_CACHE *, (MATCH (search_keywords) AGAINST(' +(>firstWord <firstWord*) +(>secondWord <secondWord*) +(>thirdWord <thirdWord*)' IN BOOLEAN MODE)) AS Relevance
FROM table WHERE
(MATCH (search_keywords) AGAINST('+(>firstWord <firstWord*)' IN BOOLEAN MODE)) AND
(MATCH (search_keywords) AGAINST('+(>secondWord <secondWord*)' IN BOOLEAN MODE)) AND
(MATCH (search_keywords) AGAINST('+(>thirdWord <thirdWord*)' IN BOOLEAN MODE)) AND
....
GROUP BY ...
ORDER BY ....
LIMIT ...



Т.е. один оператор матча мы разделили на 3 и соединили их AND - прирост в 7 раз!
Хотелось бы спросить знающих - почему?
Т.е. почему технически это происходит, експлейн в обеих запросах показывает одно и то же ..
Прошу дать ответ или ссылку, где можно разобраться.

Неактивен

 

#2 15.04.2011 21:13:06

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Match against. Разделение матчей

А что показывает explain, если не секрет?  У меня есть ощущение, что FTS
во всех случаях, а второе просто легче считать.

Неактивен

 

#3 15.04.2011 21:23:44

YAAP
Завсегдатай
Зарегистрирован: 17.02.2010
Сообщений: 31

Re: Match against. Разделение матчей

paulus написал:

А что показывает explain, если не секрет?  У меня есть ощущение, что FTS
во всех случаях, а второе просто легче считать.

Не секрет
В 1-м случае
id     select_type     table     type     possible_keys     key     key_len     ref     rows     Extra
1     SIMPLE     sq_20110413     fulltext     search_price,search_keywords     search_keywords     0           1     Using where; Using filesort

Во втором
id     select_type     table     type     possible_keys     key     key_len     ref     rows     Extra
1     SIMPLE     sq_20110413     fulltext     search_price,search_keywords     search_keywords     0           1     Using where; Using filesort


Если уж затронули тему експлейна - почему rows = 1 ?? их-то намного больше...

Неактивен

 

#4 16.04.2011 01:32:41

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Match against. Разделение матчей

rows = 1 — это просто число. Оно имеет смысл для обычного индекса и всегда равно
единице для полнотекстового. А вот то, как используется индекс, мы тут не поймем.
Скорее всего, индекс используется для выборки первого куска WHERE, а потом идет
уже обработка всех полученных строк в памяти.

Кстати, а сортируете Вы по какому-то независимому столбцу?

Неактивен

 

#5 16.04.2011 14:09:43

YAAP
Завсегдатай
Зарегистрирован: 17.02.2010
Сообщений: 31

Re: Match against. Разделение матчей

В данном конкретном случае сортировка такая
ORDER BY (Relevance * search_priority_cat) DESC, search_price ASC

Где -
`search_price` decimal(12,2) NOT NULL DEFAULT '0.00',
`search_priority_cat` int(2) NOT NULL DEFAULT '5',
KEY search_price (search_price),

Ну и (MATCH (search_keywords) AGAINST(' +(>firstWord <firstWord*) +(>secondWord <secondWord*) +(>thirdWord <thirdWord*)' IN BOOLEAN MODE)) AS Relevance

Т.о. по полю search_priority_cat нет индекса (но не уверен, что он поможет в случае высчитывания релевантности.
Пытался экспериментировать с сортировкой, ставил только релевантность или только цену - результат эксплейна один и тот же
id     select_type     table     type     possible_keys     key     key_len     ref     rows     Extra
1     SIMPLE     sq_20110413     fulltext     search_price,search_keywords     search_keywords     0           1     Using where; Using filesort

Неактивен

 

#6 16.04.2011 21:51:53

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Match against. Разделение матчей

Брр, какой кошмар smile

Обычное использование полнотекстового индекса — просто поиск по нему
один раз в WHERE. При этом гарантируется, что данные будут вытаскиваться
в порядке обратном relevance.

Почему быстрее срабатывает короткий запрос — не очень понятно, но, видимо,
Вы вытаскиваете немного строк в любом случае, и дополнительная беготня
по индексу сложнее, чем проверка, что строки соответствуют всем условиям.
В этом случае скорее всего, разбиение запроса в определении relevance тоже
должно ускорить запрос.

Неактивен

 

#7 16.04.2011 22:56:06

YAAP
Завсегдатай
Зарегистрирован: 17.02.2010
Сообщений: 31

Re: Match against. Разделение матчей

Запрос достался мне от знакомого, попросили оптимизировать.
Оставить просто полнотекстовый поиск не получится, в системе заложена (как я понимаю) еще и логика важности определенных категорий. Т.о. конечная релевантность высчитывается как (релевантность поиска * важность категории).

Разбиение match against  в определении релевантности никакого эффекта не дал, на скорость выполнения запроса это не повлияло.

Отредактированно YAAP (18.04.2011 13:44:38)

Неактивен

 

#8 18.04.2011 16:35:28

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Match against. Разделение матчей

Странно. Боюсь, что я на эту тему ничего больше сказать не смогу: Вы используете
индекс нестандартным способом и очень странно. Видимо, дальше что-то со скоростью
можно делать только путем экспериментирования.

Неактивен

 

#9 18.04.2011 17:57:24

YAAP
Завсегдатай
Зарегистрирован: 17.02.2010
Сообщений: 31

Re: Match against. Разделение матчей

paulus написал:

Странно. Боюсь, что я на эту тему ничего больше сказать не смогу: Вы используете
индекс нестандартным способом и очень странно. Видимо, дальше что-то со скоростью
можно делать только путем экспериментирования.

Спасибо и на этом, будем менять логику, видимо..

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson