1

メールメッセージに含まれる単語を格納する非常に大きなテーブルがあります

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

テーブルには約 1 億行が含まれます mwr_message_id は
メッセージ テーブルへの FK です

最も使用されている単語を計算するには、次のクエリを使用します

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;

ほぼ永久に実行されます (テスト サーバーで 30 分以上)

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)

クエリを「高速化」するためにできることはありますか (RAM の追加、CPU の追加、ディスクの高速化は別として)。

事前にありがとう
ステファノ

PS EXPLAIN 結果:

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)
4

3 に答える 3

1

mwr_message_id と mwr_word_id によるインデックスがあるのか​​、mwr_word_id のみによるインデックスなのか、主キー以外のインデックスがあるのか​​、私にはわかりませんでした。mwr_word_id によるインデックスがない場合 (または mwr_word_id を最初のフィールドとして持っている場合) は、追加することをお勧めします。

すでにそのようなインデックスを持っていて、これが非常に一般的なシナリオであるために本当に苦痛である場合は、すべての mwr_message_id で mwr_word_id の合計出現回数を合計する単語テーブルに冗長性を追加することをお勧めします。

また、いくつかのトリガーを t_message_words に追加して、この冗長性の更新を処理することもできます。

于 2010-04-22T13:16:20.613 に答える
0

UPD: このクエリを 1 回実行する必要がある場合は、完了するまで待ちます。このクエリを何度も実行する必要がある場合 - 一意の単語でテーブルを作成し、挿入/更新/削除ごとにトリガーを介してこのテーブルのカウントを更新します

于 2010-04-22T13:19:06.237 に答える
0

おそらく、上のインデックスmwr_word_idが役立つでしょう。これはキーの一部になりましたが、純粋にそのためのキーを追加できます。

構成ファイルで mysql のキャッシュを増やすこともできます。

于 2010-04-22T12:59:51.857 に答える