我正在使用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时,性能有明显的差异。select查询显示了一个优化的执行计划,只有一个完整的表扫描,而对于视图,则有两个完整的表扫描。
查询统计(由MySQL工作台测量):
选择查询
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进行了测试,也出现了同样的问题
发布于 2020-01-30 07:37:01
在这种情况下,MySQL必须对视图使用TEMPTABLE算法(聚合函数)。这可能是造成这种差异的原因。
有关更多细节,您可以参考https://dev.mysql.com/doc/refman/5.6/en/view-algorithms.html。
如果不能使用合并算法,则必须使用临时表。如果视图包含下列任何结构,则无法使用合并:
聚合函数(SUM()、MIN()、MAX()、COUNT()等)
分异
按组
有
限制
工会或工会
选择列表中的子查询
分配给用户变量
只引用文字值(在本例中,没有底层表)
发布于 2020-01-30 10:25:25
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;https://stackoverflow.com/questions/59980367
复制相似问题