[英]MySQL View performance issue with aggregate query
我正在使用 mysql 版本 5.6.47。 我有以下学生分数表:
CREATE TABLE `studentmarks` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`StudentID` int(11) NOT NULL,
`subjectName` varchar(255) DEFAULT NULL,
`MARKS` int(11) NOT NULL,
PRIMARY KEY (`ID`),
KEY `idx_studentmarks_StudentID` (`StudentID`)
);
并在表上创建了一个视图:
CREATE OR REPLACE VIEW `vw_student_marks` AS
SELECT
`s1`.`StudentID` AS `StudentID`,
`s1`.`subjectName` AS `subjectName`,
`s1`.`MARKS` AS `marks`,
(SELECT
SUM(`s2`.`MARKS`)
FROM
`studentmarks` `s2`
WHERE
(`s2`.`StudentID` = `s1`.`StudentID`)) AS `totalMarks`
FROM
`studentmarks` `s1`;
在使用大约 20K 行进行测试时,运行SELECT query
与SELECT * FROM VIEW
性能存在显着差异。 选择查询显示了一个优化的执行计划,只有 1 次全表扫描,而对于视图,有 2 次全表扫描。
查询统计信息(由 MySQL Workbench 测量):
选择查询
Timing: 0:00:0.07677120 (as measured by the server)
Rows Examined: 108285
从视图查询中选择:
Timing: 0:00:1.6082441 (as measured by the server)
Rows Examined: 2985730
这种性能差异背后的原因是什么?
查询执行计划: https : //i.stack.imgur.com/noOxI.jpg
更新:我用 MySQL 8.0.19 版测试,出现同样的问题
在这种情况下,MySQL 必须对视图使用 TEMPTABLE 算法(聚合函数)。 这可能是造成差异的原因。
您可以参考https://dev.mysql.com/doc/refman/5.6/en/view-algorithms.html了解更多详情。
如果无法使用 MERGE 算法,则必须改用临时表。 如果视图包含以下任何结构,则不能使用 MERGE:
聚合函数(SUM()、MIN()、MAX()、COUNT() 等)
清楚的
通过...分组
有
限制
联合或联合所有
选择列表中的子查询
分配给用户变量
仅指字面值(在这种情况下,没有基础表)
FWIW,我会使用不相关的子查询来写这个(但我接受它不一定会提高性能) - 并且完全放弃使用视图的想法......
SELECT s1.StudentID
, s1.subjectName
, s1.MARKS
, s2.totalmarks
FROM studentmarks s1
JOIN
( SELECT studentid
, SUM(s2.MARKS) totalmarks
FROM studentmarks
GROUP
BY studentid
) s2
ON s2.studentid = s1.studentid;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.