MySQL и таблицы предварительной сортировки - PullRequest
2 голосов
/ 30 августа 2011

У меня есть база данных MySQL на моем сервере с одной таблицей с первичным индексом и полнотекстовой индексацией по всем другим столбцам.Обычно я выполняю оператор SELECT, например:

SELECT * FROM myTable WHERE MATCH(myInfo) AGAINST ('stuff') ORDER BY id LIMIT 30

Это работает нормально, но медленно - предложение ORDER BY id значительно замедляет работу, особенно когда многохитов, как часто бывает.Например, без поиска по пунктам поиск занимает ~ 0,001 секунды, а с предложением - 0,6 секунды (но дает идеальные результаты).

  1. Можно ли предварительно отсортировать таблицу так, чтобы я некогда-нибудь нужен оператор ORDER BY?Таблица является статической - данные будут только когда-либо прочитаны.В конце концов, необходимость сортировки 5000 попаданий только для возврата (верхняя часть) 30 кажется пустой тратой, когда это можно легко решить заранее.

  2. Если нет, что я могу с этим поделать?

PS - MATCH, кажется, перемешивает вещи, тогда как LIKE, хотя медленный нет и поэтому не нуждается ORDER BY.

%% Редактировать# 1, с выводом EXPLAIN SELECT в phpMyAdmin

id  select_type table   type    possible_keys   key key_len ref rows    Extra

1   SIMPLE  myTable fulltext    full_index  full_index  0       1   Using where

Edit # 2, лучше EXPLAIN

указывает на то, что время потрачено на сортировку результатов.

Status Time

начиная с 0,000016

проверка кэша запросов для запроса 0,000048

Открытие таблиц 0,000012

Блокировка системы 0,000007

Блокировка таблицы 0,000024

init 0.000026

оптимизация 0.000010

статистика 0.000017

подготовка 0.000012

инициализация FULLTEXT 0.000199

выполнение 0.000004

Результат сортировки 0,001663

Отправка данных 0,000304

конец 0,000005

конец запроса 0,000004

освобождение элементов 0,000025

сохранение результатов в кеше запросов 0,000007

ведение журнала медленных запросов 0,000003

очистка 0,000005

Ответы [ 2 ]

1 голос
/ 31 августа 2011

Попробуйте это:

SELECT * FROM myTable WHERE MATCH(myInfo) AGAINST ('stuff') > 0.25 ORDER BY id LIMIT 30

MATCH(...) AGAINST(...) возвращает счет совпадения в диапазоне [0,1] (также называемый «релевантностью»). Промежуточные результаты можно удалить, отфильтровав строки с низкой релевантностью (> 0.25 в запросе выше; если вы не укажете это в предложении WHERE, это то же самое, что указать > 0). Значение 0.25 является произвольным, попробуйте найти хороший баланс между временем запроса и ложными отрицаниями.

примечание: я не могу гарантировать, что вы получите одинаковые результаты во всех случаях, но я действительно не понимаю, как еще это можно сделать.

1 голос
/ 30 августа 2011

1-Можно ли предварительно отсортировать мой стол?

Нет, таблица уже предварительно отсортирована ПК.
Полнотекстовый индекс вынуждает обращаться к строкам в порядке, определяемом этим индексом.
По этой причине их необходимопереупорядочено впоследствии.

2- что я могу с этим сделать?

Если вы не против получить несколько иные результаты, вы можете изменить запрос на

  SELECT * FROM 
    (
    SELECT * FROM myTable WHERE MATCH(myInfo) AGAINST ('stuff') LIMIT 30
    ) as s ORDER BY id 

. Чтобы получить следующие 30 результатов, выполните limit 30,30 и т. Д.

Вы также можете ускорить запрос, выбрав не все строки, а только те, которые вам нужны.Это ограничит объем данных, которые MySQL должен хранить в памяти, и, следовательно, объем данных, которые необходимо перемещать при сортировке.

SELECT id, myinfo FROM mytable ....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...