如何使用MYSQL(每行的子查询)优化这些指令?

时间:2013-01-21 20:52:00

标签: mysql

我的问题是我们做了一个选择,然后,对于每一行,我们运行4个不同的请求SQL(疯狂),因为你可以猜测我们做了很多请求,并且使用它的系统非常慢。

SELECT 
    deal_source.id, 
    deal_source.source_name, 
    deal_source.spider_status, 
    spider.last_success_date
FROM deal_source 
JOIN spider 
ON deal_source.id = spider.deal_source_id

然后,对于此查询的每一行,我们进行:

$total_query = "SELECT count(id) as total
                FROM spider_log 
                WHERE deal_source_id = '$deal_source_id' 
                AND date_format(date_created, '%Y-%m-%d') = '$lastdate' ";

$added_query = "SELECT count(id) as added
                FROM spider_log 
                WHERE deal_source_id = '$deal_source_id' 
                AND action = 'added'  
                AND date_format(date_created, '%Y-%m-%d') = '$lastdate' ";

$extended_query = "SELECT count(id) as extended 
                   FROM spider_log 
                   WHERE deal_source_id = '$deal_source_id' 
                   AND action = 'extended'  
                   AND date_format(date_created, '%Y-%m-%d') = '$lastdate' ";

$duplicate_query = "SELECT count(id) as duplicate 
                    FROM spider_log 
                    WHERE deal_source_id = '$deal_source_id' 
                    AND action = 'duplicate'  
                    AND date_format(date_created, '%Y-%m-%d') = '$lastdate' ";

2 个答案:

答案 0 :(得分:3)

SELECT   d.id,
         d.source_name,
         d.spider_status,
         s.last_success_date,
         COUNT(l.id) AS total,
         SUM(l.id IS NOT NULL AND l.action='added'    ) AS added,
         SUM(l.id IS NOT NULL AND l.action='extended' ) AS extended,
         SUM(l.id IS NOT NULL AND l.action='duplicate') AS duplicate
FROM     deal_source d
    JOIN spider      s
      ON s.deal_source_id  = d.id
    JOIN spider_log  l
      ON l.deal_source_id  = d.id
      ON l.date_created   >= s.last_success_date
     AND l.date_created   <  s.last_success_date + INTERVAL 1 DAY
GROUP BY d.id

答案 1 :(得分:3)

有些观点:

  • 您可以使用EXPLAIN并谨慎添加索引来优化每个查询的效果。

  • 您可以将所有查询组合成一个大查询,这样您就不必通过大量查询来访问数据库。

  • 除了大量的查询之外,date_format(date_created, '%Y-%m-%d') = '$lastdate'是一个性能杀手,因为它将一个函数(DATE_FORMAT())用于一个列(date_created),因此不能使用任何索引并且该函数被称为thosuand或数百万次(检查多行)。将这些条件(无论它们在您的代码中)更改为:

     (  date_created >= DATE('$lastdate') 
    AND date_created < DATE('$lastdate') + INTERVAL 1 DAY
     )
    

    甚至更好,如果$lastdate是日期,请:

     (  date_created >= '$lastdate' 
    AND date_created < '$lastdate' + INTERVAL 1 DAY
     )
    

    如果date_createdDATE列,则更好:

        date_created = '$lastdate'