2016-12-14 53 views
1

我正在創建一個包含3列的報表:當天的總計數,pt_scanid的計數,這些表對於表和當天的日期而言總共是唯一的。如何避免在MySQL請求中加入表

這裏是表模式:

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計劃。

+1

主要的原因在於連接速度很慢,因爲它看起來像你不使用索引,你還應該包括的輸出'EXPLAIN [your_query]'這裏 –

+2

'SELECT *'不應該用'組使用'。想想看...列返回的不是聚合的,也不是聚合鍵。 –

+0

我添加了pt_created的索引並附上了查詢的解釋 – Rooleek

回答

1
  1. 請勿選擇不需要的字段。 MySQL 可能足夠聰明,可以忽略子查詢中的SELECT *,但我不會對它下注。
  2. 避免在條件上使用函數調用;如果pt_created被索引,DATE()將使查詢忽略索引;如果pt_created沒有索引,它應該是。

    WHERE(DATE(c.pt_created)> = '2016年10月6日' 和日期(c.pt_created)< = '二〇一六年十二月一十四日')

會更好,更高效爲:

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 
+0

我每天加入一組獨特的'pt_scanid',然後我將它們按天計數 – Rooleek

+0

COUNT(DISTINCT'pst'.'pt_scanid')AS'uniq' - 這將在**這一天**中返回唯一的'pt_scanid',但是我需要爲**整個**表完全unqiue'pt_scanid'。 – Rooleek

+0

我建議在單獨的查詢中這樣做。 – Uueerdo