【问题标题】:mysql query taking too much time for processing. how to solve this issue [closed]mysql 查询处理时间过长。如何解决这个问题[关闭]
【发布时间】:2012-08-17 12:07:57
【问题描述】:
 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  

【问题讨论】:

  • 如果您希望有人帮助您,您需要提供更多详细信息。

标签: mysql select count


【解决方案1】:

有 3 个突出的地方可以改进:

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 输出。
  • 写下现在需要多长时间,以及您希望它有多快。您总是可以进行更多优化,因此您需要一个目标,否则这是一场没有尽头的练习。

【讨论】:

  • 是的。我重新计算了两次值。你能简化这个mysql查询吗?谢谢回复
  • 能否请您下次发布格式正确的 SQL?重新格式化需要大量时间。
  • 您好,它的工作速度更快。但是当我运行此查询时,我无法获得总值 desc 顺序。非常感谢
  • 为什么不呢?问题是什么?不要让我们猜测。
  • 比以前快 20 倍。谢谢这个。但它不是按总值排序
【解决方案2】:

尝试单独运行order by里面的select,然后在原始查询中使用结果。
此外,您在子查询中使用了同一个表 tracking 两次 - 您应该将子选择合并为一个并使用 caseif
如果您需要更多帮助,您将必须运行Explain 并向我们展示结果。

【讨论】:

  • 请解释一下并举一些例子
  • 我不能explain只有你可以;)
猜你喜欢
  • 1970-01-01
  • 2021-05-07
  • 1970-01-01
  • 2016-10-22
  • 2020-10-21
  • 2019-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多