我的数据库中有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
的数据插入class
(id
,code
,subject
)值
(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);
我在示例中仅添加了几条记录,但是我要显示数千条记录。有更好的查询吗?预先感谢
答案 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