1

我有以下 MySQL 查询,它运行良好,但有时运行速度非常慢。

    SELECT s.ID AS  `Student_ID` , IFNULL( COUNT( f.ID ) , 0 ) AS  `Flags` , IFNULL( COUNT( i.ID ) , 0 ) AS  `Interventions` 
    FROM  `frog_shared`.`student` s
    LEFT JOIN  `frog_flags`.`flags` f ON s.ID = f.`Student_ID` 
    LEFT JOIN  `frog_flags`.`interventions` i ON s.ID = i.`Student_ID` 
    WHERE s.ID
    IN ( 132336 ) 
    GROUP BY s.ID
    ORDER BY s.Surname ASC , s.Firstname DESC 

基本上,给定一个学生 ID 列表,我希望我的系统返回Flags他们收到的数量和Interventions.

但是,当有大约 30 名学生的列表时,查询需要将近一秒钟的时间才能运行。

ed时的查询结果EXPLAIN如下:

解释结果

student.id我在and上有索引flags.Student_ID,所以我认为这不是问题。

我还能如何优化我的查询?

更新:SHOW CREATE表格

CREATE TABLE `interventions` (
 `ID` int(10) NOT NULL auto_increment,
 `Visible` int(1) NOT NULL,
 `Student_ID` int(6) NOT NULL COMMENT 'FK frog_shared.student',
 `Staff_ID` int(6) NOT NULL COMMENT 'FK frog_shared.staff',
 `Datetime` datetime NOT NULL,
 `Category_ID` int(3) NOT NULL COMMENT 'FK intervention_categories',
 `Generation_Type` varchar(1) NOT NULL COMMENT '[A]utomated or [M]anual',
 `Reason` text NOT NULL,
 `Status` varchar(1) NOT NULL COMMENT '[O]pen, In [P]rogress, [C]losed',
 PRIMARY KEY  (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1

CREATE TABLE `flags` (
 `ID` int(10) NOT NULL auto_increment,
 `Student_ID` int(6) NOT NULL COMMENT 'FK frog_shared.student',
 `Staff_ID` int(6) NOT NULL COMMENT 'FK frog_shared.staff',
 `Datetime` datetime NOT NULL,
 `Period_ID` int(2) NOT NULL COMMENT 'FK frog_shared.periods',
 `Location_ID` int(3) NOT NULL COMMENT 'FK frog_shared.locations',
 `Category_ID` int(2) NOT NULL COMMENT 'FK flag_categories',
 `Alert_ID` int(11) default NULL COMMENT 'FK frog_alerts.alerts',
 `Action_Taken_Category_ID` int(1) default NULL COMMENT 'FK frog_flags.categories FA',
 `Action_Taken_Status` varchar(1) default NULL COMMENT '[P]ending or [C]omplete',
 `Details` text NOT NULL,
 PRIMARY KEY  (`ID`),
 KEY `Student_ID` (`Student_ID`),
 KEY `Staff_ID` (`Staff_ID`),
 KEY `Datetime` (`Datetime`)
) ENGINE=InnoDB AUTO_INCREMENT=3669 DEFAULT CHARSET=latin1

CREATE TABLE `student` (
 `id` varchar(20) default NULL,
 `UPN` varchar(25) NOT NULL,
 `Firstname` varchar(50) NOT NULL,
 `Surname` varchar(50) NOT NULL,
 `Year_Group` int(2) NOT NULL,
 `Tutor_Group` varchar(15) NOT NULL,
 `SEN_Status` varchar(1) default NULL,
 `Flags` varchar(10) default NULL,
 PRIMARY KEY  (`UPN`),
 KEY `id` (`id`),
 KEY `Year_Group` (`Year_Group`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
4

2 回答 2

3

我建议摆脱 GROUP BY 和 JOIN,因为它们似乎没有必要获得您想要的结果。

SELECT 
s.ID AS  `Student_ID` , 
(
    SELECT COUNT(*) FROM `frog_flags`.`flags` f
    WHERE s.ID = f.`Student_ID`
) AS  `Flags` ,
(
    SELECT COUNT(*) FROM `frog_flags`.`interventions` i
    WHERE s.ID = i.`Student_ID`
) AS  `Interventions` 
FROM  `frog_shared`.`student` s
WHERE s.ID
IN ( 132336 ) 
ORDER BY s.Surname ASC , s.Firstname DESC

确保索引打开interventions.Student_ID,当您在该表中获取一些数据时,您应该很高兴。

让我知道此重构是否有任何问题。

于 2013-11-05T09:21:19.590 回答
1

在 mysql 中,profiling 查询的步骤是

首先执行

set profiling=1;

然后执行您要分析的查询

<your query>

然后执行

show PROFILES;

它会给出类似的结果

+----------+------------+-----------------------------+
| Query_ID | Duration   | Query                       |
+----------+------------+-----------------------------+
|        1 | 0.00057500 | Your query
+----------+------------+-----------------------------+

然后执行

show Profile for query 1;

结果喜欢

+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000105 |
| checking permissions | 0.000014 |
| Opening tables       | 0.000026 |
| System lock          | 0.000006 |
| Table lock           | 0.000051 |
| init                 | 0.000044 |
| optimizing           | 0.000009 |
| statistics           | 0.000019 |
| preparing            | 0.000014 |
| executing            | 0.000213 |
| end                  | 0.000031 |
| query end            | 0.000004 |
| freeing items        | 0.000030 |
| logging slow query   | 0.000004 |
| cleaning up          | 0.000005 |

告诉结果,一个需要更多时间来执行的检查。这是一个用于优化 mysql 查询的好文档:http ://www.percona.com/files/presentations/percona-live/dc-2012/PLDC2012-mysql-query-optimization.pdf

于 2013-10-24T12:33:24.860 回答