我有一个显示门票购买情况的数据库,大约80万条记录。所有表格都是InnoDB格式的。较慢的查询是:
SELECT e.id AS id, e.name AS name, e.url AS url, p.action AS action, gk.key AS `key`
FROM event AS e
LEFT JOIN participation AS p ON p.event=e.id
LEFT JOIN goldenkey AS gk ON gk.issuedto=p.person
WHERE p.person='139160'
OR p.person IS NULL;此查询来自PDO,因此引用了p.person。JOIN和WHERE中使用的所有列都已编入索引。p.event是约束到e.id的外键,gk.issuedto和p.person是约束到未提及的表person.id的外键。所有这些都是INT。表e很小-只有10行。表p大约有500,000行,此时gk为空。
此查询在人员的详细信息页面上运行。我们想要得到所有事件的列表,如果有参与行,他们的参与,如果有金钥匙行,那么他们的金钥匙。
慢查询日志提供:
Query_time: 12.391201 Lock_time: 0.000093 Rows_sent: 2 Rows_examined: 466104EXPLAIN SELECT提供了:
+----+-------------+-------+------+---------------+----------+---------+----------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+----------+---------+----------------+------+-------------+
| 1 | SIMPLE | e | ALL | NULL | NULL | NULL | NULL | 10 | |
| 1 | SIMPLE | p | ref | event | event | 4 | msadb.e.id | 727 | Using where |
| 1 | SIMPLE | gk | ref | issuedto | issuedto | 4 | msadb.p.person | 1 | |
+----+-------------+-------+------+---------------+----------+---------+----------------+------+-------------+对于给定的p.person,此查询在第一次运行时运行7~12秒,然后在未来运行<0.05秒。删除OR p.person IS NULL不会缩短查询时间。当p的大小从~20k增加到~500k (导入旧数据)时,此查询就会变慢。
有没有人对如何提高性能有什么建议?记住,总体目标是检索所有事件的列表,如果有参与行,则他们的参与,如果有金钥匙行,则他们的金钥匙。如果多个查询会更有效,我可以这样做。
发布于 2011-07-25 09:26:08
如果您可以摆脱p.person IS NULL,请尝试以下操作,看看它是否有帮助:
SELECT e.id AS id, e.name AS name, e.url AS url, p.action AS action, gk.key AS `key`
FROM event AS e
LEFT JOIN participation AS p ON (p.event=e.id AND p.person='139160')
LEFT JOIN goldenkey AS gk ON gk.issuedto=p.person发布于 2011-07-25 09:23:35
为了笑..。将关键字"STRAIGHT_JOIN“添加到您的选择...
SELECT STRAIGHT_JOIN ... rest of query...发布于 2011-07-25 09:24:11
我不确定您有多少索引和表的模式,但请尽量避免使用空值。默认情况下,它会显著降低查询速度。
https://stackoverflow.com/questions/6810952
复制相似问题