Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
提高查询性能/在MySQL上更快地重写查询_Mysql_Sql - Fatal编程技术网

提高查询性能/在MySQL上更快地重写查询

提高查询性能/在MySQL上更快地重写查询,mysql,sql,Mysql,Sql,我有几个查询使用数据库中当前的数据运行得非常慢(几分钟),我想提高它们的性能。不幸的是,它们有点复杂,所以我通过谷歌获得的信息不足以让我确定要添加哪些索引,或者我是否需要重写我的查询或什么。。。我希望有人能帮忙。我不认为他们应该这么慢,如果事情安排得当的话 第一个查询是: SELECT i.name, i.id, COUNT(c.id) FROM cert_certificates c JOIN cert_histories h ON h.cert_certificate_id = c.id

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

第一个查询是:

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
选择识别号、识别号、计数(c.id)
来自证书c
在h.cert\u certificate\u id=c.id上加入证书
h.inspector_id=i.id上的左外连接检验者i
左外连接证书
ON(h2.cert\u certificate\u id=c.id和h.date\u changed
第二个问题是:

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
选择l.字母、c.编号
来自证书c
在c上加入证书类型字母参考l。证书类型字母参考id=l.id
在h.cert\u certificate\u id=c.id上加入证书
左外连接证书
ON(h2.cert\u certificate\u id=c.id和h.date\u changed
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:第一个查询的解释结果是(对不起,格式太糟糕了;我正在使用SQLyog,它在一个漂亮的表中显示,但StackOverflow似乎不支持表?)

id选择\u类型表类型可能的\u键\u长度参考行额外 1简单h所有空19740使用where;使用临时设备;使用文件排序 1个简单的i参考索引\u检查员\u id索引\u检查员\u id 768营销\u开发。h.检查员\u id 1 1个简单的c参考索引证书id上的证书索引id上的证书768 marketing\u development.h.cert\u certificate\u id 91,使用where;使用索引 1简单h2所有空19740使用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 id选择\u类型表类型可能的\u键\u长度参考行额外 1简单h所有空19795使用where;使用临时设备;使用文件排序 1简单c参考索引证书id上的证书索引id上的证书768营销开发h证书id 91使用何处 1简单l所有索引证书类型字母参考id NULL 5使用where;使用连接缓冲区
1 SIMPLE h2 ALL NULL 19795使用where应在连接字段上创建索引:

cert_certificates.cert_type_letter_ref_id
cert_histories.cert_certificate_id
cert_histories.date_changed
cert_histories.inspector_id

那没用。我仍然不知道问题出在哪里。将排除连接更改为
不存在是否有帮助?呃。。。我的意思是你可以把
EXPLAIN
的结果包含在这里,不是吗?用
EXPLAIN your_query
的完整输出编辑你的问题,这样我们可以给你更好的建议。顺便说一句,我错过了什么吗;为什么需要在
JOIN
条件中包含`AND h.date\u changedcert_certificates.cert_type_letter_ref_id cert_histories.cert_certificate_id cert_histories.date_changed cert_histories.inspector_id