我正在执行一个查询,将行转换为类似于this post的列,但遇到了性能问题。这是查询: -
SELECT
Info.Customer,
Answers.Answer,
Answers.AnswerDescription,
Details.Code1,
Details.Code2,
Details.Code3
FROM
Info
LEFT OUTER JOIN Answers
ON Info.AnswerID = Answers.AnswerID
LEFT OUTER JOIN
(SELECT
ReferenceNo,
MAX(CASE DetailsIndicator WHEN 'cde1' THEN DetailsCode ELSE NULL END ) Code1,
MAX(CASE DetailsIndicator WHEN 'cde2' THEN DetailsCode ELSE NULL END ) Code2,
MAX(CASE DetailsIndicator WHEN 'cde3' THEN DetailsCode ELSE NULL END ) Code3
FROM DetailsData
GROUP BY ReferenceNo) Details
ON Info.ReferenceNo = Details.ReferenceNo
WHERE Info.Date BETWEEN x AND y
返回的行数少于300行,但“详细信息”表约为18万行。 查询需要45秒才能在一半的时间内运行。 请注意,内部查询需要7秒才能运行。
当我在MYSQL中输入show processlist;
时,它挂在“发送数据”上。
有关性能问题可能是什么的任何想法?
答案 0 :(得分:2)
首先,查询“详细信息”结果的内部子选择是查询所有条目...这是你想要的吗?我不这么认为。您似乎只希望根据符合外部日期检查的参考编号获得结果。
所以,我会改变你的内部选择以包括......
FROM DetailsData
where DetailsData.ReferenceNo IN
( select distinct Info2.ReferenceNo
from Info Info2 where Info2.Date between x and y )
GROUP BY ReferenceNo) Details
这样,您只能获得与相关日期范围内的参考号相关的详细信息。
答案 1 :(得分:1)
首先,我将在子查询中移动where.dd和Details和Info的连接。
此外,Details.ReferenceNo和Info.Date是否已编入索引?
编辑: 好吧,这是我想到的版本
SELECT
Details.Customer,
Answers.Answer,
Answers.AnswerDescription,
Details.Code1,
Details.Code2,
Details.Code3
FROM
(SELECT
Info.Customer,
Info.AnswerID,
Info.ReferenceNo,
MAX(CASE DetailsIndicator WHEN 'cde1' THEN DetailsCode ELSE NULL END ) Code1,
MAX(CASE DetailsIndicator WHEN 'cde2' THEN DetailsCode ELSE NULL END ) Code2,
MAX(CASE DetailsIndicator WHEN 'cde3' THEN DetailsCode ELSE NULL END ) Code3
FROM Info LEFT JOIN DetailsData ON Info.ReferenceNo = Details.ReferenceNo
WHERE Info.Date BETWEEN x AND y
GROUP BY ReferenceNo) Details
LEFT OUTER JOIN Answers ON Details.AnswerID = Answers.AnswerID
所以第一次迭代是减少子查询中生成的记录数(原因:它的源有几百条记录,并且有聚合,所以mysql必须构建一个结果集以便进一步加入) - 在感觉DRapp的解决方案与此类似。
但问题是,是否真的有必要提供子查询?看看下面将如何执行
将是有意义的SELECT
Info.Customer,
Answers.Answer,
Answers.AnswerDescription,
MAX(CASE DetailsIndicator WHEN 'cde1' THEN DetailsCode ELSE NULL END ) Code1,
MAX(CASE DetailsIndicator WHEN 'cde2' THEN DetailsCode ELSE NULL END ) Code2,
MAX(CASE DetailsIndicator WHEN 'cde3' THEN DetailsCode ELSE NULL END ) Code3
FROM
FROM Info
LEFT JOIN DetailsData ON Info.ReferenceNo = DetailsData.ReferenceNo
LEFT OUTER JOIN Answers ON Details.AnswerID = Answers.AnswerID
WHERE Info.Date BETWEEN x AND y
GROUP BY ReferenceNo
鉴于结果中只有数百条记录,并且如果有索引覆盖连接和选择条件,我希望上面的内容在适度的硬件上以不到一秒的速度返回结果。
(查询未经测试)
答案 2 :(得分:0)
尝试使用“EXPLAIN”来定义哪个查询很慢