2

それらの間に外部キー制約がある2つのテーブルがあります

Table event
mysql> describe event;
+------------+------------------+------+-----+---------+-------+
| Field      | Type             | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+-------+
| sid        | int(10) unsigned | NO   | PRI | NULL    |       |
| cid        | int(10) unsigned | NO   | PRI | NULL    |       |
| signature  | int(10) unsigned | NO   | MUL | NULL    |       |
| timestamp  | datetime         | NO   | MUL | NULL    |       |
| is_deleted | tinyint(1)       | NO   | MUL | 0       |       |
+------------+------------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

Table signature
mysql> describe signature;
+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| sig_id       | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| sig_name     | varchar(255)     | NO   | MUL | NULL    |                |
| sig_class_id | int(10) unsigned | NO   | MUL | NULL    |                |
| sig_priority | int(10) unsigned | YES  |     | NULL    |                |
| sig_rev      | int(10) unsigned | YES  |     | NULL    |                |
| sig_sid      | int(10) unsigned | YES  |     | NULL    |                |
| sig_gid      | int(10) unsigned | YES  |     | NULL    |                |
+--------------+------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

event.signature は外部キーであり、signature.sig_id にリンクしています。どちらにもインデックスがあります

テーブル イベントは大きい (たとえば 100 万レコード) のに対し、テーブル シグネチャは比較的小さい (せいぜい数千)

署名属性にアクセスする結合クエリは、実行に非常に長い時間がかかります。説明を見て

mysql> explain select event.sid,event.cid,signature.sig_name from event join signature on signature.sig_id=event.signature;
+----+-------------+-----------+------+--------------------------------+-----------------------+---------+-------------------------+------+--------------------------+
| id | select_type | table     | type | possible_keys                  | key                   | key_len | ref                     | rows | Extra                    |
+----+-------------+-----------+------+--------------------------------+-----------------------+---------+-------------------------+------+--------------------------+
|  1 | SIMPLE      | signature | ALL  | PRIMARY,index_signature_sig_id | NULL                  | NULL    | NULL                    |  127 |                          |
|  1 | SIMPLE      | event     | ref  | index_event_signature          | index_event_signature | 5       | snorby.signature.sig_id |   68 | Using where; Using index |
+----+-------------+-----------+------+--------------------------------+-----------------------+---------+-------------------------+------+--------------------------+
2 rows in set (0.00 sec)

署名属性がアクセスされない場合

mysql> explain select event.sid,event.cid from event join signature on signature.sig_id=event.signature;
+----+-------------+-----------+-------+--------------------------------+------------------------+---------+-------------------------+------+--------------------------+
| id | select_type | table     | type  | possible_keys                  | key                    | key_len | ref                     | rows | Extra                    |
+----+-------------+-----------+-------+--------------------------------+------------------------+---------+-------------------------+------+--------------------------+
|  1 | SIMPLE      | signature | index | PRIMARY,index_signature_sig_id | index_signature_sig_id | 4       | NULL                    |  127 | Using index              |
|  1 | SIMPLE      | event     | ref   | index_event_signature          | index_event_signature  | 5       | snorby.signature.sig_id |   68 | Using where; Using index |
+----+-------------+-----------+-------+--------------------------------+------------------------+---------+-------------------------+------+--------------------------+
2 rows in set (0.00 sec)

署名属性が照会されるとわかるように、すべての結合タイプでフル スキャンが実行されます。

より高速になるようにクエリを書き直すことは可能ですか? これは複数のテーブル結合の一部であり、署名付きの結合イベントがクエリを大幅に遅くしているボトルネックであるため、これを尋ねます

ORM として 5.1.52 MySQL と SQLAlchemy 0.7.8 を使用しています

4

1 に答える 1

1

定義上、クエリにはフル スキャンが必要です。

つまり、フィルタリング条件を指定しません。いいえ... WHERE sig_rev = 17、たとえば。

したがって、ここで改善することはあまりありません。MySQL は開始するテーブルを選択し、フル スキャンを実行し、行ごとに 2 番目のテーブルから一致する行をフェッチします。

したがって、スキャンは不可欠です。ただし、テーブル スキャンの代わりにインデックス スキャンに変更することもできます。signature列のみ、および列のみにインデックスがあると想定していますsig_id

あなたができることはsig_id, sig_name、次のように に追加のインデックスを作成することです:

ALTER TABLE signature ADD UNIQUE INDEX(sig_id, sig_name);

インデックスは よりも広いため、定義上は一意ですPRIMARY KEYが、これは要点の範囲外です。

今得られるのは、投稿した 2 番目の例に似た実行計画ですsignature

この特定のクエリでパフォーマンスが向上することを比較して確認してください。INSERT新しいインデックスがパフォーマンスなどに悪影響を与えていないことを確認してください。

幸運を。

于 2012-07-12T11:10:42.927 に答える