我一直在搞亂整天試圖找到爲什麼我的查詢性能很糟糕。這非常簡單,但可能需要15分鐘才能執行(我在該階段中止查詢)。我加入了一張有超過200萬條記錄的表格。MySQL加入性能極差
這是選擇:
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
這是EXPLAIN
| 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 |
這是模式:
# 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)
);
需要注意一些非常重要的事項 - 'audit'或'alerts'中的MessageID不是1:1; MessageID可以存在於一個表中,但不能存在於另一個表中,或者可以存在於兩者中(這是我加入的目的);在我的測試數據庫中,都沒有的MessageID存在。換句話說,我的查詢將返回230萬記錄,其中0作爲計數。
另一件需要注意的是用於使用MessageID作爲varchar(255)的'audit'和'alert'表。我創建了'消息'表,期望它能修復連接。它實際上使其更糟糕。以前,它需要78秒,現在,它永遠不會返回。
我對MySQL有什麼想法?
解決了這個問題。謝謝謝謝!如果可以的話,我會給你+10。 – Blazes 2012-02-17 16:37:28