我有几个查询对我数据库中当前的数据运行非常缓慢(几分钟),我想提高它们的性能。不幸的是,它们有点复杂,所以我通过谷歌获得的信息不足以让我弄清楚要添加哪些索引,或者我是否需要重写我的查询或什么......我希望有人能提供帮助。如果事情设置得当,我认为他们不应该这么慢。
第一个查询是:
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 表与 cert_histories 表一样包含近 19k 条记录(尽管未来该表预计将增长到 cert_certificates 表大小的大约 2-3 倍)。其他的桌子都很小;每条记录少于 10 条。
现在唯一的索引是每个表的 id 和 cert_certificates.number。我在几个地方(例如这里)阅读以添加外键索引,但在 cert_histories 表的情况下,几乎所有列(cert_certificate_id、inspector_id、cert_status_ref_id)也是不可取的(根据一些该问题的答案,例如 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 使用 where;使用临时的;使用文件排序 1 简单我参考 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 在哪里使用;使用索引 1 SIMPLE h2 ALL NULL NULL NULL NULL 19740 使用 where
第二个查询:
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE h ALL NULL NULL NULL NULL 19795 使用 where;使用临时的;使用文件排序 1 SIMPLE c ref index_cert_certificates_on_id index_cert_certificates_on_id 768 marketing_development.h.cert_certificate_id 91 使用 where 1 SIMPLE l ALL index_cert_type_letter_refs_on_id NULL NULL NULL 5 使用 where;使用连接缓冲区 1 SIMPLE h2 ALL NULL NULL NULL NULL 19795 使用 where