MYSQL减少了多个子查询的执行时间

时间:2019-02-21 02:15:25

标签: php mysql database

我的数据库中有3个表,我正在查询数千条记录,这使我的查询变慢,我的主查询有两个对记录进行计数的子查询。尽管我得到了我想要的输出,但我只是想知道是否还有其他方法可以减少查询的执行时间以提高效率。

所需的输出
classid-类代码-评估类-validatedinclass

使用此sql查询执行500条以上的记录大约需要2分钟

SELECT mainclass.id, mainclass.code, (SELECT Count(e.enrollno) FROM enrolldet AS e Inner Join enroll ON e.enrollno = enroll.enrollno Inner Join class ON e.classid= class.id WHERE enroll.assessed = '1' AND mainclass.id = class.id) as assessedinclass, (SELECT Count(e.enrollno) FROM enrolldet AS e Inner Join enroll ON e.enrollno = enroll.enrollno Inner Join class ON e.classid= class.id WHERE enroll.validated = '1' AND mainclass.id = class.id) as validatedinclass FROM class AS mainclass Left Join enrolldet ON mainclass.id = enrolldet.classid Left Join enroll ON enrolldet.enrollno = enroll.enrollno GROUP BY mainclass.id, mainclass.code

数据库

class

CREATE TABLE IF NOT EXISTS `class` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `code` varchar(10) NOT NULL,
  `subject` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

-

-转储表class的数据

插入classidcodesubject)值 (1,'A1',1), (2,'A2',2), (3,'A3',3), (4,'A4',4);

enroll

CREATE TABLE IF NOT EXISTS `enroll` (
  `enrollno` int(11) NOT NULL AUTO_INCREMENT,
  `student` int(11) NOT NULL,
  `acctok` tinyint(1) NOT NULL,
  `assessed` tinyint(1) NOT NULL,
  `validated` tinyint(1) NOT NULL,
  PRIMARY KEY (`enrollno`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

-

-转储表enroll的数据

INSERT INTO `enroll` (`enrollno`, `student`, `acctok`, `assessed`, `validated`) VALUES
(1, 1, 1, 1, 0),
(2, 2, 1, 1, 1),
(3, 3, 1, 1, 0),
(4, 4, 0, 0, 0),
(5, 5, 1, 1, 1);  

enrolldet

CREATE TABLE IF NOT EXISTS `enrolldet` (
  `enrollno` int(11) NOT NULL,
  `classid` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-

-转储表enrolldet的数据

INSERT INTO `enrolldet` (`enrollno`, `classid`) VALUES
(1, 1),
(1, 2),
(1, 3),
(1, 4),
(2, 1),
(2, 2),
(2, 3),
(2, 4),
(3, 1),
(3, 2),
(3, 3),
(3, 4),
(4, 1),
(4, 2),
(4, 3),
(4, 4),
(5, 1),
(5, 2),
(5, 3);

我在示例中仅添加了几条记录,但是我要显示数千条记录。有更好的查询吗?预先感谢

1 个答案:

答案 0 :(得分:1)

对表达式求和而不是对子查询求和。假设总有匹配项,那么使用JOIN而不是LEFT JOIN可以节省一些记录检索。

SELECT class.id, class.code,
  SUM(enroll.assessed =  '1') as assessedinclass,
  SUM(enroll.validated =  '1') as validatedinclass
FROM class
JOIN enrolldet ON class.id = enrolldet.classid
JOIN enroll ON enrolldet.enrollno = enroll.enrollno
GROUP BY class.id, class.code