如何避免在MySQL请求中连接表

时间:2016-12-14 17:29:13

标签: php mysql

我创建了一个包含3列的报告表:当天的总计数,pt_scanid 的计数,这对于表格来说是唯一的以及当天的日期

这是表架构:

CREATE TABLE IF NOT EXISTS `partners_scanstracking` (
`pt_id` int(11) NOT NULL AUTO_INCREMENT,
`pt_partner_id` int(5) NOT NULL,
`pt_ip` varchar(30) NOT NULL,
`pt_scanid` varchar(50) NOT NULL,
`pt_fn` varchar(20) DEFAULT NULL,
`pt_url` mediumtext,
`pt_created` datetime NOT NULL,
PRIMARY KEY (`pt_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=0;

以下是我创建的请求:

SELECT COUNT(DISTINCT `c`.`pt_created`) AS `count`,
       COUNT(DISTINCT `x`.`pt_scanid`) AS `uniq`,
       `c`.`pt_created`
FROM `partners_scanstracking` c
LEFT JOIN
  (SELECT `x`.*
   FROM
     (SELECT *
      FROM `partners_scanstracking`
      WHERE `pt_partner_id` = '0'
      ORDER BY `pt_created` ASC) x
   GROUP BY `pt_scanid`) x ON DATE(`c`.`pt_created`)=DATE(`x`.`pt_created`)
WHERE (DATE(`c`.`pt_created`) >= '2016-10-06'
       AND DATE(`c`.`pt_created`) <= '2016-12-14')
  AND `c`.`pt_partner_id` = '0'
GROUP BY DATE(`c`.`pt_created`)
ORDER BY `c`.`pt_created` ASC

Explain

之前一切都运转良好,但现在该表有500.000条记录,请求太慢。我想主要原因是我加入了两张大桌子。

我不知道如何优化查询或避免在此加入。

有人可以帮助我吗?

PS:如果没有什么可以优化我认为我需要为计算结果创建表并使用crons schedule。

1 个答案:

答案 0 :(得分:1)

  1. 不要选择不需要的字段。 MySQL 可能足够聪明,可以忽略子查询中的SELECT *,但我不会赌它。
  2. 避免在条件上使用函数调用;如果pt_created被索引,DATE()将使查询忽略索引;如果没有索引pt_created,它应该是。

    WHERE(日期(c.pt_created)&gt; ='2016-10-06'及日期(c.pt_created)&lt; ='2016-12-14')

  3. 会更好,效率更高:

    c.pt_created BETWEEN '2016-10-06 00:00:00' AND '2016-12-14 23:59:59'
    

    相关地,目前还不清楚应该做什么:

    ON DATE(`c`.`pt_created`)=DATE(`x`.`pt_created`)
    

    有什么特殊要求导致了查询而不是像这样的事情?

    SELECT COUNT(DISTINCT `pst`.`pt_created`) AS `count`,
           COUNT(DISTINCT `pst`.`pt_scanid`) AS `uniq`,
           DATE(`c`.`pt_created`) AS theDate
    FROM `partners_scanstracking` AS pst
    WHERE pst.pt_created BETWEEN '2016-10-06 00:00:00' AND '2016-12-14 23:59:59'
      AND pst.`pt_partner_id` = '0'
    GROUP BY theDate
    ORDER BY theDate ASC