Полнотекстовый поиск "title" в 1M строках - PullRequest
4 голосов
/ 06 февраля 2012

Имеется таблица Myisam 3.3 ГБ articles со следующими полями: id, title, perma, body, date первичный ключ: id полнотекстовый индекс: title

Имеет 1110 000 строк. После того как я сделал это:

SET GLOBAL key_buffer_size = 2000*1024*1024; LOAD INDEX INTO CACHE articles INDEX(title);

Мне не хватает производительности.

Ниже вы можете увидеть время выполнения нескольких примеров:

<9.5381848812103>
SELECT SQL_NO_CACHE perma,title,body, MATCH(title) AGAINST('flowers for children' IN BOOLEAN MODE) AS sort
FROM articles  WHERE MATCH(title) AGAINST('flowers for children' IN BOOLEAN MODE) ORDER BY sort DESC LIMIT 30;

<12.734259843826>
SELECT SQL_NO_CACHE perma,title,body, MATCH(title) AGAINST('how to play basketball' IN BOOLEAN MODE) AS sort
FROM articles  WHERE MATCH(title) AGAINST('how to play basketball' IN BOOLEAN MODE) ORDER BY sort DESC LIMIT 30;

<4.4655818939209>
SELECT SQL_NO_CACHE perma,title,body, MATCH(title) AGAINST('kill a bird and eat it' IN BOOLEAN MODE) AS sort
FROM articles  WHERE MATCH(title) AGAINST('kill a bird and eat it' IN BOOLEAN MODE) ORDER BY sort DESC LIMIT 30;

<16.268588066101>
SELECT SQL_NO_CACHE perma,title,body, MATCH(title) AGAINST('avoid back pain' IN BOOLEAN MODE) AS sort
FROM articles  WHERE MATCH(title) AGAINST('avoid back pain' IN BOOLEAN MODE) ORDER BY sort DESC LIMIT 30;

<12.553371906281>
SELECT SQL_NO_CACHE perma,title,body, MATCH(title) AGAINST('computer' IN BOOLEAN MODE) AS sort
FROM articles  WHERE MATCH(title) AGAINST('computer' IN BOOLEAN MODE) ORDER BY sort DESC LIMIT 30;

Есть предложения по улучшению времени выполнения?

Ответы [ 2 ]

0 голосов
/ 07 февраля 2012

Вот ваш первый запрос

SELECT SQL_NO_CACHE perma,title,body,
MATCH(title) AGAINST('flowers for children' IN BOOLEAN MODE) AS sort
FROM articles
WHERE MATCH(title) AGAINST('flowers for children' IN BOOLEAN MODE)
ORDER BY sort DESC LIMIT 30;

Возможно, вам понадобится рефакторинг этого

Сначала выберите ключи и значение сортировки

SELECT id,MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE) sort
FROM articles
WHERE MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE);

Этот запросВ результате получится временная таблица 800M

Далее, ограничьте ее 30 самыми высокими значениями сортировки

SELECT * FROM
(
    SELECT id,MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE) sort
    FROM articles
    WHERE MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE)
) AA
ORDER BY sort DESC LIMIT 30;

Хорошо, теперь временная таблица 720 байт

Наконец, LEFT JOIN те30 строк в таблице articles

SELECT
    B.perma,B.title,B.body,A.sort
FROM
(
    SELECT * FROM
    (
        SELECT id,MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE) sort
        FROM articles
        WHERE MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE)
    ) AA
    ORDER BY sort DESC LIMIT 30
) A LEFT JOIN articles B USING (id);

Попробуйте !!!

0 голосов
/ 07 февраля 2012

Попробуйте просто использовать значение по умолчанию «В НОРМАЛЬНОМ РЕЖИМЕ» вместо «В БУЛЕВОМ РЕЖИМЕ».

Я не уверен, есть ли какая-либо конкретная причина, по которой вы выбрали «В БУЛЕВОМ РЕЖИМЕ».Я заметил, что вы не используете ни одного из операторов, которые предлагает «В БУЛЕВОМ РЕЖИМЕ».Кроме того, из-за большого набора данных вам не нужно беспокоиться о 50% -ном пороге.

Я предлагаю это, потому что «В НОРМАЛЬНОМ РЕЖИМЕ» также отсортирует результаты по релевантности без необходимости «СОРТИРОВАТЬ ПО".Это соответствует документации MySQL .

О, и если вы не изменили минимальный размер слова, кратчайшие слова, включенные в «ИНДЕКС ПОЛНОГО ТЕКСТА», имеют длину 4 буквы.Таким образом, «for» в вашем «AGAINST (...)» будет ненужным, если только размер минимального слова не был изменен.

...