mysql查询花费了太多时间进行处理。如何解决这个问题

时间:2012-08-22 05:33:48

标签: mysql select count

 SELECT car_detail.*,
       (SELECT Count(tdid)
        FROM   testdrive
        WHERE  testdrive.carid = car_detail.detail_id)            AS vipdrive,
       (SELECT Count(fid)
        FROM   finanace_app
        WHERE  finanace_app.classified_id = car_detail.detail_id) AS financeapp,
       (SELECT Count(trid)
        FROM   tracking
        WHERE  tracking.carid = car_detail.detail_id
               AND track_mode = 'C')                              AS craigimp,
       (SELECT Count(trid)
        FROM   tracking
        WHERE  tracking.carid = car_detail.detail_id
               AND track_mode = 'L')                              AS landing
FROM   car_detail
WHERE  year <= '2011'
       AND price != '0'
       AND photo_count != ''
ORDER  BY (SELECT Count(tdid)
           FROM   testdrive
           WHERE  testdrive.carid = car_detail.detail_id)
          + (SELECT Count(fid)
             FROM   finanace_app
             WHERE  finanace_app.classified_id = car_detail.detail_id)
          + (SELECT Count(trid)
             FROM   tracking
             WHERE  tracking.carid = car_detail.detail_id)
          + car_detailed + picture_view + map_view
          + video_view DESC  

2 个答案:

答案 0 :(得分:1)

有三件事情可以改进:

1)

选择列表中的相关子查询。一般的子查询和相关的子查询特别慢,因为它们是针对主查询的每一行运行的。您可以将这些重写为from子句中的子查询并加入它们。

2)

按顺序查询表达式。由于与SELECT列表中的子查询相同的原因,它们很慢。在这种情况下,你实际上是在重新计算已有的值,所以你要做两次工作。您应该参考选择列表中的列。

3)

您要查询跟踪表两次,一次是track_mode ='L',一次是track_mode ='C'。查询一次并根据track_mode

的值计算两个计数更有意义
SELECT     car_detail.*
,          vipdrive.testdrives
,          financeapp.finance_count
,          craigimp.tracking_count
,          craigimp.landing_count
FROM       car_detail
LEFT JOIN  (
           SELECT   Count(tdid) testdrives
           ,        testdrive.carid
           FROM     testdrive
           GROUP BY testdrive.carid
           )        vipdrive
ON         car_detail.detail_id = vipdrive.carid
LEFT JOIN  (
           SELECT   Count(fid) finance_count
           ,        finanace_app.classified_id
           FROM     finanace_app
           GROUP BY finanace_app.classified_id
           )        financeapp
ON         car_detail.detail_id = financeapp.classified_id
LEFT JOIN  (
           SELECT   SUM(if(track_mode = 'C', 1, 0)) tracking_count
           ,        SUM(if(track_mode = 'L', 1, 0)) landing_count
           ,        tracking.carid
           FROM     tracking
           GROUP BY tracking.carid
           )        craigimp
ON         car_detail.detail_id = craigimp.carid  
WHERE      year <= 2011
AND        price != 0
AND        photo_count != ''
ORDER  BY  vipdrive.testdrives
         + finance_count
         + tracking_count
         + car_detailed + picture_view + map_view
         + video_view DESC 

次要改进不引用数字常量。

作为效果问题的一般规则,请在将来执行以下操作:

  • 发布格式良好的SQL。请使用此http://www.dpriver.com/pp/sqlformat.htm?ref=g_wangz例如
  • 发布查询中每个表的SHOW CREATE TABLE输出
  • 为您的查询发布EXPLAIN输出。
  • 写下它现在花了多长时间,以及你希望它有多快。你可以随时优化更多,所以你需要一个目标,否则它就是一个没有尽头的练习。

答案 1 :(得分:0)

尝试分别在order by内运行select,然后在原始查询中使用结果。
另外,您在子查询中使用相同的表tracking两次 - 您应该将子选择合并为一个并使用caseif
如果您想要获得比运行Explain更多的帮助并向我们展示结果。