なぜ私のクエリのパフォーマンスがひどいのかを調べようと1日中困惑しています。非常にシンプルですが、実行に15分以上かかります(その段階でクエリを中断します)。私は200万を超えるレコードを持つテーブルに参加しています。MySQL JOINのパフォーマンスが極端に悪い
これは選択です:
SELECT
audit.MessageID, alerts.AlertCount
FROM
audit
LEFT JOIN (
SELECT MessageID, COUNT(ID) AS 'AlertCount'
FROM alerts
GROUP BY MessageID
) AS alerts ON alerts.MessageID = audit.MessageID
これはこれは、スキーマある
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
| 1 | PRIMARY | AL | index | NULL | IDX_audit_MessageID | 4 | NULL | 2330944 | 100.00 | Using index |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 124140 | 100.00 | |
| 2 | DERIVED | alerts | index | NULL | IDX_alerts_MessageID | 5 | NULL | 124675 | 100.00 | Using index |
をEXPLAINです:
# Not joining, just showing types
CREATE TABLE messages (
ID int NOT NULL AUTO_INCREMENT,
MessageID varchar(255) NOT NULL,
PRIMARY KEY (ID),
INDEX IDX_messages_MessageID (MessageID)
);
# 2,324,931 records
CREATE TABLE audit (
ID int NOT NULL AUTO_INCREMENT,
MessageID int NOT NULL,
LogTimestamp timestamp NOT NULL,
PRIMARY KEY (ID),
INDEX IDX_audit_MessageID (MessageID),
CONSTRAINT FK_audit_MessageID FOREIGN KEY(MessageID) REFERENCES messages(ID)
);
# 124,140
CREATE TABLE alerts (
ID int NOT NULL AUTO_INCREMENT,
AlertLevel int NOT NULL,
Text nvarchar(4096) DEFAULT NULL,
MessageID int DEFAULT 0,
PRIMARY KEY (ID),
INDEX IDX_alert_MessageID (MessageID),
CONSTRAINT FK_alert_MessageID FOREIGN KEY(MessageID) REFERENCES messages(ID)
);
いくつかの非常に重要なことに注意してください。 - MessageIDは 'audit'または 'alerts'の1:1ではありません。 MessageIDは1つのテーブルに存在することはできますが、他のテーブルに存在することはできません。または両方に存在する可能性があります(これは自分の参加の目的です)。私のテストDBには、がありません。どちらもMessageIDのがあります。言い換えれば、私のクエリは0としてカウント230万レコードを返します。
「audit」テーブルと「alert」テーブルは、MessageIDをvarchar(255)として使用していました。私はそれが結合を修正することを期待して 'メッセージ'テーブルを作成しました。実際にはが悪化しました以前は78秒かかりましたが、今は返されません。
MySQLについて私は何が欠けていますか?
それが問題を解決しました。ありがとうありがとう!もし私ができるなら、私はあなたに+10を与えるだろう。 – Blazes