我的CMS系統中有一個模塊,允許網站顯示廣告。它記錄視圖和點擊。我用來總結日誌的查詢表現不佳。MySQL:日誌摘要查詢
這是查詢:
SELECT `a`.`id`,
`a`.`active`,
`a`.`static`,
`a`.`position`,
`a`.`file`,
`a`.`title`,
`a`.`url`,
COUNT(DISTINCT `lv`.`id`) AS `views`,
COUNT(DISTINCT `lc`.`id`) AS `clicks`
FROM `ads` AS `a`
LEFT JOIN `ad_log` AS `lv`
ON `lv`.`ad_id` = `a`.`id`
AND `lv`.`type` = 'view'
AND `lv`.`created` BETWEEN '2011-01-01 00:00:00'
AND '2011-12-31 23:59:59'
LEFT JOIN `ad_log` AS `lc`
ON `lc`.`ad_id` = `a`.`id`
AND `lc`.`type` = 'click'
AND `lc`.`created` BETWEEN '2011-01-01 00:00:00'
AND '2011-12-31 23:59:59'
GROUP BY `a`.`id`
ORDER BY `a`.`static` DESC,
`a`.`position` ASC,
`a`.`title` ASC
的ad_log
表對ad_id
和type
列的兩列的索引。當我查看分析器結果時,它使用該索引。一個不同的索引會更高效嗎?
UPDATE
測試不同的指數組合後,似乎目前的一個是最好的。也許有更好的方法來編寫查詢?
這裏是EXPLAIN SELECT SQL_NO_CACHE ...
抓屏:
SOLUTION
我已經接受DRapp's solution,但這裏是我會拿出查詢。這只是略低於高性能比DRapp's solution:
SELECT `a`.`id`,
`a`.`active`,
`a`.`static`,
`a`.`position`,
`a`.`file`,
`a`.`title`,
`a`.`url`,
(SELECT COUNT(*)
FROM `ad_log`
WHERE `ad_id` = `a`.`id`
AND `type` = 'view'
AND `created` BETWEEN '2011-11-01 00:00:00'
AND '2011-11-30 23:59:59') AS `views`,
(SELECT COUNT(*)
FROM `ad_log`
WHERE `ad_id` = `a`.`id`
AND `type` = 'click'
AND `created` BETWEEN '2011-11-01 00:00:00'
AND '2011-11-30 23:59:59') AS `clicks`
FROM `ads` AS `a`
ORDER BY `a`.`static` DESC,
`a`.`position` ASC,
`a`.`title` ASC
最好的性能
這個查詢,通過DRapp's solution啓發,具有更好的性能:
SELECT `a`.`id`,
`a`.`active`,
`a`.`static`,
`a`.`position`,
`a`.`file`,
`a`.`title`,
`a`.`url`,
SUM(CASE WHEN `l`.`type` = 'view' THEN 1 ELSE 0 END) AS `views`,
SUM(CASE WHEN `l`.`type` = 'click' THEN 1 ELSE 0 END) AS `clicks`
FROM `ads` AS `a`
LEFT JOIN `ad_log` AS `l`
ON `a`.`id` = `l`.`ad_id`
AND `l`.`created` BETWEEN '2011-11-01 00:00:00'
AND '2011-11-30 23:59:59'
GROUP BY `a`.`id`
ORDER BY `a`.`static` DESC,
`a`.`position` ASC,
`a`.`title` ASC
出於興趣也可以張貼EXPLAIN SELECT的輸出SQL_NO_CACHE .....其餘查詢 –
發佈輸出解釋查詢。 – theking963
@AdrianCornish和@ daking963 - 我發佈了'EXPLAIN SELECT SQL_NO_CACHE'結果的屏幕截圖 – Sonny