我有几个查询运行速度很慢(几分钟),目前我的数据库中有数据,我想提高它们的性能。不幸的是它们有点复杂,所以我通过谷歌获取的信息不足以让我弄清楚要添加的索引,或者我是否需要重写我的查询或者什么......我希望有人可以提供帮助。如果事情设置得当,我不会认为他们应该这么慢。
第一个查询是:
SELECT i.name, i.id, COUNT(c.id)
FROM cert_certificates c
JOIN cert_histories h ON h.cert_certificate_id = c.id
LEFT OUTER JOIN inspectors i ON h.inspector_id = i.id
LEFT OUTER JOIN cert_histories h2
ON (h2.cert_certificate_id = c.id AND h.date_changed < h2.date_changed)
WHERE (h.cert_status_ref_id = ? OR h.cert_status_ref_id = ?)
AND h2.id IS NULL
GROUP BY i.id, i.name
ORDER BY i.name
第二个查询是:
SELECT l.letter, c.number
FROM cert_certificates c
JOIN cert_type_letter_refs l ON c.cert_type_letter_ref_id = l.id
JOIN cert_histories h ON h.cert_certificate_id = c.id
LEFT OUTER JOIN cert_histories h2
ON (h2.cert_certificate_id = c.id AND h.date_changed < h2.date_changed)
WHERE h.cert_status_ref_id = ?
AND h2.id IS NULL
AND h.inspector_id = ?
ORDER BY l.letter, c.number
cert_certificates表包含近19k条记录,cert_histories表也是如此(尽管将来该表预计会增长到cert_certificates表大小的2-3倍)。其他表都很小;每个不到10个记录。
现在唯一的索引是每个表和cert_certificates.number的id。我读了几个地方(例如here)来为外键添加索引,但是在cert_histories表的情况下,几乎所有的列(cert_certificate_id,inspector_id,cert_status_ref_id)也是{{ 3}}(根据该问题的一些答案,例如Markus Winand的),所以我有点迷失。
非常感谢任何帮助。
ETA:EXPLAIN在第一个查询中的结果是(抱歉可怕的格式化;我正在使用SQLyog将它呈现在一个漂亮的表中,但似乎StackOverflow不支持表?):
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE h ALL NULL NULL NULL NULL 19740 Using where; Using temporary; Using filesort 1 SIMPLE i ref index_inspectors_on_id index_inspectors_on_id 768 marketing_development.h.inspector_id 1 1 SIMPLE c ref index_cert_certificates_on_id index_cert_certificates_on_id 768 marketing_development.h.cert_certificate_id 91 Using where; Using index 1 SIMPLE h2 ALL NULL NULL NULL NULL 19740 Using where
第二次查询:
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE h ALL NULL NULL NULL NULL 19795 Using where; Using temporary; Using filesort 1 SIMPLE c ref index_cert_certificates_on_id index_cert_certificates_on_id 768 marketing_development.h.cert_certificate_id 91 Using where 1 SIMPLE l ALL index_cert_type_letter_refs_on_id NULL NULL NULL 5 Using where; Using join buffer 1 SIMPLE h2 ALL NULL NULL NULL NULL 19795 Using where
答案 0 :(得分:1)
您应该在连接字段上创建索引:
cert_certificates.cert_type_letter_ref_id
cert_histories.cert_certificate_id
cert_histories.date_changed
cert_histories.inspector_id