Справка по производительности MySQL - PullRequest
1 голос
/ 22 апреля 2010

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

mysql> explain t_message_words;
+----------------+---------+------+-----+---------+----------------+
| Field          | Type    | Null | Key | Default | Extra          |
+----------------+---------+------+-----+---------+----------------+
| mwr_key        | int(11) | NO   | PRI | NULL    | auto_increment |
| mwr_message_id | int(11) | NO   | MUL | NULL    |                |
| mwr_word_id    | int(11) | NO   | MUL | NULL    |                |
| mwr_count      | int(11) | NO   |     | 0       |                |
+----------------+---------+------+-----+---------+----------------+

таблица содержит около 100 миллионов строк
mwr_message_id - это таблица FK для сообщений
mwr_word_id - это таблица FK для слов
mwr_count - количество вхождений слова mwr_word_id в сообщение mwr_message_id

. Для вычисления наиболее часто используемых слов я использую следующий запрос

SELECT SUM(mwr_count) AS word_count, mwr_word_id
FROM t_message_words
GROUP BY mwr_word_id
ORDER BY word_count DESC
LIMIT 100;

, который выполняется почти вечно (более получасана тестовом сервере)

mysql> show processlist;
+----+------+----------------+--------+---------+------+----------------------+-----------------------------------------------------
| Id | User | Host           | db     | Command | Time | State                | Info
+----+------+----------------+--------+---------+------+----------------------+-----------------------------------------------------
processlist
| 41 | root | localhost:3148 | tst_db | Query   | 1955 | Copying to tmp table | SELECT SUM(mwr_count) AS word_count, mwr_word_id
    FROM t_message_words
    GROUP BY mwr_word_id |
+----+------+----------------+--------+---------+------+----------------------+-----------------------------------------------------
3 rows in set (0.00 sec)

Что я могу сделать, чтобы "ускорить" запрос (кроме добавления большего количества оперативной памяти, большего количества процессоров, более быстрых дисков)?

спасибо взаранее
Стефано

PS ОБЪЯСНИТЬ результат:

mysql> EXPLAIN SELECT SUM(mwr_count) AS word_count, mwr_word_id
    -> FROM t_message_words
    -> GROUP BY mwr_word_id
    -> ORDER BY word_count DESC
    -> LIMIT 100;
+----+-------------+-----------------+-------+---------------+----------------------+---------+------+----------+---------------------------------+
| id | select_type | table           | type  | possible_keys | key                  | key_len | ref  | rows     | Extra                           |
+----+-------------+-----------------+-------+---------------+----------------------+---------+------+----------+---------------------------------+
|  1 | SIMPLE      | t_message_words | index | NULL          | IDX_t_message_words2 | 4       | NULL | 94823285 | Using temporary; Using filesort |
+----+-------------+-----------------+-------+---------------+----------------------+---------+------+----------+---------------------------------+
1 row in set (0.01 sec)

Ответы [ 3 ]

1 голос
/ 22 апреля 2010

Я не понял, есть ли у вас индекс по mwr_message_id и mwr_word_id, или просто по mwr_word_id, или любой другой индекс, отличный от индекса первичного ключа. Если у вас нет индекса по mwr_word_id (или в качестве первого поля указано mwr_word_id), я предлагаю вам добавить его.

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

И вы также можете добавить некоторые триггеры к t_message_words для обработки обновлений этой избыточности.

0 голосов
/ 22 апреля 2010

UPD: если вам нужно выполнить этот запрос один раз - просто дождитесь его завершения. Если вам нужно многократно выполнять этот запрос - создайте таблицу с уникальными словами и количество обновлений в этой таблице с помощью триггера каждую вставку / обновление / удаление

0 голосов
/ 22 апреля 2010

Возможно, индекс на mwr_word_id поможет. Теперь это часть ключа, но вы можете добавить ключ исключительно для этого.

Вы также можете увеличить кэш mysql в файле конфигурации.

...