簡體   English   中英

MySQL 查看聚合查詢的性能問題

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM