SQL子查询比任何一个查询运行都慢

时间:2013-01-30 04:58:11

标签: sql phpmyadmin subquery average

从PHPMyAdmin执行时,我有两个查询可以自行运行 - 几秒钟内。

SELECT * FROM `testresults` WHERE `SCH_NAME` <> ''

SELECT AVG(pass_rate) FROM `testresults` WHERE `SCH_NAME` <> ''

但是,当我使用第二个查询作为子查询时,查询运行速度非常慢,以至于我达到最大执行时间并且什么也得不到。

SELECT 
      * 
FROM `testresults` 
WHERE pass_rate > (SELECT 
                      AVG(pass_rate) 
                   FROM `testresults` 
                     WHERE `SCH_NAME` <> ''
                  ) 
 AND `SCH_NAME` <> ''

似乎正在为每一行执行子查询,尽管该平均值将是常量。在我的查询中是否有不正确的东西导致它被解释为每行的平均变化?怎么可以改写?

3 个答案:

答案 0 :(得分:0)

尝试子查询。未经测试但是这样的事情:

SELECT * FROM 
    `testresults` as tr , 
    (select avg(pass_rate) as passrate from testresults) as tr2
WHERE tr.`SCH_NAME` <> ''
and   tr.passrate > tr2.passrate

答案 1 :(得分:0)

这适用于Transact SQL:

   select
    testresults.*
   from
    testresults
       inner join 
         (
              select 
                  AVG(pass_rate) as calculated_avg 
              from testresults 
               where sch_name <> ''
         ) p 
           on (testresults.pass_rate > p.calculated_avg)
    where sch_name <> ''

答案 2 :(得分:0)

您的表格中有很多记录有sch_name空白,即SCH_NAME=''

尝试在外部选择查询的WHERE子句中更改条件位置。 条件从左到右评估。

SELECT 
      * 
FROM `testresults` 
WHERE `SCH_NAME` <> '' AND pass_rate > (SELECT 
                                         AVG(pass_rate) 
                                        FROM `testresults` 
                                        WHERE `SCH_NAME` <> ''
                                      ) 

如果记录有SCH_NAME='',则不会对子查询进行评估,即使用 AND 运算符时,如果第一个条件的计算结果为false,则不评估第二个条件。这称为sh ort circuiting

更好的方法是评估AVG(pass_rate)一次,将结果存储在变量中,并在where where而不是subquery中使用此变量。

 Declare @var int
    SET @var = (SELECT  AVG(pass_rate) 
               FROM `testresults` 
               WHERE `SCH_NAME` <> '')

     SELECT 
              * 
        FROM `testresults` 
        WHERE `SCH_NAME` <> '' AND pass_rate >@var