Stu*_*eld 10 mysql performance explain sql-execution-plan
我有一个与解释相关的基本MySQL性能问题.我有两个返回相同结果的查询,我试图了解如何理解EXPLAIN执行计划.
该表中有50000条记录,我正在进行记录比较.我的第一个查询需要18.625秒才能运行.解释计划如下.
id select_type table type possible_keys key key_len ref rows filtered Extra
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 SIMPLE a ALL NULL NULL NULL NULL 49520 100.00
1 SIMPLE b ref scoreEvent,eventScore eventScore 4 olympics.a.eventId 413 100.00 Using where; Using index; Not exists
1 SIMPLE c ref PRIMARY,scoreEvent,eventScore scoreEvent 8 olympics.a.score,olympics.a.eventId 4 100.00 Using where; Using index; Not exists
Run Code Online (Sandbox Code Playgroud)
我的下一个查询需要0.106秒才能运行...
id select_type table type possible_keys key key_len ref rows filtered Extra
-----------------------------------------------------------------------------------------------------------------------------------
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 50000 100.00 Using temporary; Using filesort
2 DERIVED results ALL NULL NULL NULL NULL 49520 100.00 Using filesort
Run Code Online (Sandbox Code Playgroud)
在文档中,它说ALL需要全表扫描,这非常糟糕.它还说filesort需要额外的传递来对记录进行排序,它还说这Not exists意味着MySQL能够进行LEFT JOIN优化.同样清楚的是,第一种方法是使用索引,而第二种方法则不然.
我正在尝试弄清楚这里发生了什么以及涉及到什么数学.我RESET QUERY CACHE在测试之间运行,以确保没有任何不公平的优势.49520 x 413 x 4比50000 x 49520小很多.
这与id解释计划有关吗?
当我测试这些和其他查询时,似乎我的观察结果是查询复杂性可以通过将具有相同id的项相乘并将每个id的结果加在一起来近似...这是一个有效的假设吗?
正如评论中所要求的那样,架构和查询只是在它有所帮助的情况下,但我并不是在寻找更好的查询...仅仅是一个解释EXPLAIN.有问题的表......
CREATE TABLE results (
resultId INT NOT NULL auto_increment KEY,
athleteId INT NOT NULL,
eventId INT NOT NULL,
score INT NOT NULL,
CONSTRAINT FOREIGN KEY (athleteId) REFERENCES athletes(athleteId),
CONSTRAINT FOREIGN KEY (eventId) REFERENCES events(eventId),
INDEX eventScore (eventId, score),
INDEX scoreEvent (score, eventId)
) ENGINE=innodb;
Run Code Online (Sandbox Code Playgroud)
第一个查询......
SELECT a.resultId, a.eventId, a.athleteId, a.score
FROM results a
-- Find records with matching eventIds and greater scores
LEFT JOIN results b
ON b.eventId = a.eventId
AND b.score > a.score
-- Find records with matching scores and lesser testIds
LEFT JOIN results c
ON c.eventId = a.eventId
AND c.score = a.score
AND c.resultId < a.resultId
-- Filter out all records where there were joins
WHERE c.resultId IS NULL
AND b.resultId IS NULL;
Run Code Online (Sandbox Code Playgroud)
第二个问题......
SELECT resultId, athleteId, eventId, score
FROM (
SELECT resultId, athleteId, eventId, score
FROM results
ORDER BY eventId, score DESC, resultId
) AS a
GROUP BY eventId;
Run Code Online (Sandbox Code Playgroud)
我还注意到,如果我删除eventScore查询下降到2.531秒的索引,并且执行计划没有那么大的改变,但possible_keys的顺序发生了变化而且不是Using index表b(忽略行数的微小变化,我正在生成每次我更改架构时的数据)...
id select_type table type possible_keys key key_len ref rows filtered Extra
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 SIMPLE a ALL NULL NULL NULL NULL 47457 100.00
1 SIMPLE b ref eventId,scoreEvent eventId 4 olympics.a.eventId 659 100.00 Using where; Not exists
1 SIMPLE c ref PRIMARY,eventId,scoreEvent scoreEvent 8 olympics.a.score,olympics.a.eventId 5 100.00 Using where; Using index; Not exists
Run Code Online (Sandbox Code Playgroud)
事实上,当你看到这些数字时,你不应该相乘,而应该相加。在您的情况下,比较 (49520 x 413 x 4) 和 (50000 + 49520)。
一般规则很简单:汇总所有段(派生的、主要的)并在每个段内乘以行。
id select_type ... rows
1 PRIMARY 1
1 PRIMARY 2
2 DERIVED 3
2 DERIVED 4
3 DERIVED 5
3 DERIVED 6
Run Code Online (Sandbox Code Playgroud)
复杂度为:1*2 + 3*4 + 5*6
| 归档时间: |
|
| 查看次数: |
2877 次 |
| 最近记录: |