2

我有几个查询对我数据库中当前的数据运行非常缓慢(几分钟),我想提高它们的性能。不幸的是,它们有点复杂,所以我通过谷歌获得的信息不足以让我弄清楚要添加哪些索引,或者我是否需要重写我的查询或什么......我希望有人能提供帮助。如果事情设置得当,我认为他们不应该这么慢。

第一个查询是:

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
4

1 回答 1

1

您应该在连接字段上创建索引:

cert_certificates.cert_type_letter_ref_id
cert_histories.cert_certificate_id
cert_histories.date_changed
cert_histories.inspector_id
于 2012-10-29T18:11:16.980 回答