[英]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.