嘿,我有一个使用嵌套子查询的MySQL查询。
我已经尝试了很多方法来加快速度,因为它需要大约2秒才能运行,并且会减慢网页速度。
如何加快此查询?我已经尝试过使用视图和查询缓存,但性能优势是名义上的。
SELECT w.WID,
max(wb.BlockPrice) as highestPrice,
min(wb.BlockPrice) as lowestPrice,
max(bi.Impressions) as highestImpressions,
min(bi.Impressions) as lowestImpressions
FROM Website w
JOIN Website_Block wb on wb.WID = w.WID
JOIN Website_Block_Impressions wbi on wbi.WBID = wb.WBID and wbi.StatDate > DATE_SUB(NOW(),INTERVAL 1 DAY)
JOIN (
SELECT round((Sum(Impressions) / Count(impDate)) * 30) AS Impressions, WID as WIDImpressions
FROM (SELECT COUNT(wbi.WBIID) AS Impressions,
CAST(wbi.StatDate AS DATE) AS impDate,
wbi.WBID,
wb.WID
FROM Website_Block_Impressions wbi
JOIN Website_Block wb ON wb.WBID = wbi.WBID
WHERE wb.BlockEnabled = 1
AND wb.Archived = 0
AND `wbi`.StatDate > DATE_ADD(now(), INTERVAL -wb.BlockDuration DAY)
GROUP BY CAST(wbi.StatDate AS DATE), wbi.WBID) AS impressions
GROUP BY WBID) as bi
WHERE w.Archived = 0
AND w.Approved = 1
AND bi.WIDImpressions = w.WID
AND bi.Impressions between 0 AND 73000
GROUP BY w.WID
LIMIT 0,10
任何帮助都将不胜感激。
答案 0 :(得分:0)
您需要在WHERE条件上添加索引。例如,添加包含字段w.Archived
和w.Approved
的索引。如果没有这样的索引,MySQL必须首先扫描每一行,而不是确切知道它应该使用哪些行。
但是像Scrum Meister所提到的那样,我们需要查看EXPLAIN输出和表定义,以更好地了解瓶颈在哪里以及如何解决它们。
如果你不能在网上有足够的资源来帮助你理解如何创建最佳索引以提高查询速度。此幻灯片演示提供了从何处开始的基本概述:http://www.slideshare.net/manikandakumar/mysql-query-and-index-tuning
答案 1 :(得分:0)
如果您考虑要选择的内容,则可以将此减少为单个子查询。正如您正在使用COUNT,并计算您正在进行分组的内容。您可以通过一次性计算所有内容来执行相同操作,并将COUNTING DISTINCT值视为另一部分。
SELECT
w.WID,
max(wb.BlockPrice) as highestPrice,
min(wb.BlockPrice) as lowestPrice,
max(bi.Impressions) as highestImpressions,
min(bi.Impressions) as lowestImpressions
FROM
Website w
JOIN Website_Block wb on wb.WID = w.WID
JOIN Website_Block_Impressions wbi on wbi.WBID = wb.WBID and wbi.StatDate > DATE_SUB(NOW(),INTERVAL 1 DAY)
JOIN (
SELECT
ROUND((SUM(wbi.WBIID) / COUNT(DISTINCT DATE(wbi.StatDate))) * 30) AS Impressions
wb.WID
FROM
Website_Block_Impressions wbi
JOIN Website_Block wb ON wb.WBID = wbi.WBID
WHERE
wb.BlockEnabled = 1
AND wb.Archived = 0
AND `wbi`.StatDate > DATE_ADD(now(), INTERVAL -wb.BlockDuration DAY)
GROUP BY
wbi.WBID
) bi
WHERE
w.Archived = 0
AND w.Approved = 1
AND bi.WIDImpressions = w.WID
AND bi.Impressions between 0 AND 73000
GROUP BY
w.WID
LIMIT 0,10
您不需要CAST日期类型。如果它不是日期列,那么可能有些错误。铸造没有索引可以使用。
此外,考虑到mySQL使用索引的最简单方法是为所有列创建COMBINED索引,对每个表进行GROUPING或JOINing。
类似于: