就“技能名称”的子查询选择而言,下面的查询相当慢。
优化这个SQL查询的最好方法是什么?或者有没有MySQL工具可以帮助检查SQL查询的成本并优化脚本?
SELECT
CASE
WHEN(
SELECT
COUNT(ag.`PKEY`) - COUNT(ag.`ANSWERTIME`)
FROM acdcallinformation ag
WHERE (ag.`COMPLETED`) = 1 AND answertime IS NULL AND DATEofcall = DATE(NOW()) AND ag.skillid = acdcallinformation.skillid
) IS NULL
THEN
0
ELSE
(
SELECT COUNT(ag.`PKEY`) - COUNT(ag.`ANSWERTIME`)
FROM acdcallinformation ag
WHERE (ag.`COMPLETED`) = 1 AND answertime IS NULL AND DATEofcall= DATE(NOW()) AND ag.skillid = acdcallinformation.skillid)
END AS 'Lost Calls',
CASE WHEN COUNT(acdcallinformation.idleonqueue) IS NULL THEN 0 ELSE COUNT(acdcallinformation.idleonqueue) END AS 'Total Calls',
CASE WHEN COUNT(acdcallinformation.`ANSWERTIME`) IS NULL THEN 0 ELSE COUNT(acdcallinformation.`ANSWERTIME`) END AS 'Answered',
(
SELECT
skillinfo.skillname
FROM skillinfo
WHERE skillinfo.pkey = acdcallinformation.skillid
) AS Skill,
SEC_TO_TIME(AVG(TIME_TO_SEC(answertime)- TIME_TO_SEC(firstringonqueue))) AS 'Average Answer Time',
SEC_TO_TIME(AVG(TIME_TO_SEC(IDLEONQUEUE) - TIME_TO_SEC(answertime))) AS 'Average Talk Time'
FROM `acdcallinformation` acdcallinformation
WHERE DATEOFCALL = DATE(NOW())
GROUP BY skill; 不确定显示数据的最佳方式:
ACDCALLINFORMATION -当前行数3028
INSTIME PKEY DATEOFCALL CONNECTTIME FIRSTRING SKILLID
2012-07-19 14:50:16 19985 2012-07-19 14:50:16 14:50:16 5SKILLINFO -平均行数为5-10
INSTIME PKEY SKILLNAME
2012-07-01 13:12:01 1 Calls Outgoing
2012-07-01 13:12:01 2 Call Centre
2012-07-01 13:12:01 3 Accounts
2012-07-01 13:12:01 4 Reception这是预期的输出:
"Lost Calls" "Total Calls" "Answered" "Skill" "Average Answer Time" "Average Talk Time"
"1" "2" "1" "Accounts" "00:00:04" "00:00:01"
"0" "5" "5" "Service" "00:00:07" "00:01:20"发布于 2013-02-08 00:41:49
尝试使用内部连接来提高性能并避免不必要的子查询
SELECT
COALESCE(ag.skillcount, 0) AS 'Lost Calls',
CASE WHEN COUNT(acdcallinformation.idleonqueue) IS NULL THEN 0 ELSE COUNT(acdcallinformation.idleonqueue) END AS 'Total Calls',
CASE WHEN COUNT(acdcallinformation.`ANSWERTIME`) IS NULL THEN 0 ELSE COUNT(acdcallinformation.`ANSWERTIME`) END AS 'Answered',
si.skillname AS Skill,
SEC_TO_TIME(AVG(TIME_TO_SEC(answertime)- TIME_TO_SEC(firstringonqueue))) AS 'Average Answer Time',
SEC_TO_TIME(AVG(TIME_TO_SEC(IDLEONQUEUE) - TIME_TO_SEC(answertime))) AS 'Average Talk Time'
FROM `acdcallinformation` acdcallinformation
LEFT JOIN (
SELECT skillid, COUNT(`PKEY`) - COUNT(`ANSWERTIME`) skillcount
FROM acdcallinformation
WHERE (`COMPLETED`) = 1 AND answertime IS NULL AND DATEofcall = DATE(NOW())
) ag ON AND ag.skillid = acdcallinformation.skillid
LEFT JOIN skillinfo si ON si.pkey = acdcallinformation.skillid
WHERE DATEOFCALL = DATE(NOW())
GROUP BY si.skillname; 发布于 2013-02-08 00:35:30
看起来您正在尝试确保将NULL%s转换为0%s。因此:
SELECT
IFNULL(
(SELECT COUNT(ag.`PKEY`) - COUNT(ag.`ANSWERTIME`) FROM acdcallinformation ag
WHERE (ag.`COMPLETED`) = 1 AND answertime IS NULL
AND DATEofcall = DATE(NOW()) AND ag.skillid = acdcallinformation.skillid
), 0) AS 'Lost Calls',
IFNULL(COUNT(acdcallinformation.idleonqueue), 0) AS 'Total Calls',
IFNULL(COUNT(acdcallinformation.`ANSWERTIME`),0) AS 'Answered',
(
SELECT
skillinfo.skillname
FROM skillinfo
WHERE skillinfo.pkey = acdcallinformation.skillid
) AS Skill,
SEC_TO_TIME(AVG(TIME_TO_SEC(answertime)- TIME_TO_SEC(firstringonqueue))) AS 'Average Answer Time',
SEC_TO_TIME(AVG(TIME_TO_SEC(IDLEONQUEUE) - TIME_TO_SEC(answertime))) AS 'Average Talk Time'
FROM `acdcallinformation` acdcallinformation
WHERE DATEOFCALL = DATE(NOW())
GROUP BY skill;不过,使用使用此数据的语言将这些NULL转换为0可能会更容易……这只是个想法。
此外,我阅读了COUNT的文档,认为它永远不会返回NULL,因此:
SELECT
(SELECT COUNT(ag.`PKEY`) - COUNT(ag.`ANSWERTIME`) FROM acdcallinformation ag
WHERE (ag.`COMPLETED`) = 1 AND answertime IS NULL
AND DATEofcall = DATE(NOW()) AND ag.skillid = acdcallinformation.skillid
) AS 'Lost Calls',
COUNT(acdcallinformation.idleonqueue) AS 'Total Calls',
COUNT(acdcallinformation.`ANSWERTIME`) AS 'Answered',
(
SELECT
skillinfo.skillname
FROM skillinfo
WHERE skillinfo.pkey = acdcallinformation.skillid
) AS Skill,
SEC_TO_TIME(AVG(TIME_TO_SEC(answertime)- TIME_TO_SEC(firstringonqueue))) AS 'Average Answer Time',
SEC_TO_TIME(AVG(TIME_TO_SEC(IDLEONQUEUE) - TIME_TO_SEC(answertime))) AS 'Average Talk Time'
FROM `acdcallinformation` acdcallinformation
WHERE DATEOFCALL = DATE(NOW())
GROUP BY skill;最后,我认为您可以使用JOIN处理第二个查询
SELECT
IFNULL(
(SELECT COUNT(ag.`PKEY`) - COUNT(ag.`ANSWERTIME`) FROM acdcallinformation ag
WHERE (ag.`COMPLETED`) = 1 AND answertime IS NULL
AND DATEofcall = DATE(NOW()) AND ag.skillid = acdcallinformation.skillid
), 0) AS 'Lost Calls',
IFNULL(COUNT(acdcallinformation.idleonqueue), 0) AS 'Total Calls',
IFNULL(COUNT(acdcallinformation.`ANSWERTIME`),0) AS 'Answered',
skillinfo.skillname AS Skill,
SEC_TO_TIME(AVG(TIME_TO_SEC(answertime)- TIME_TO_SEC(firstringonqueue))) AS 'Average Answer Time',
SEC_TO_TIME(AVG(TIME_TO_SEC(IDLEONQUEUE) - TIME_TO_SEC(answertime))) AS 'Average Talk Time'
FROM `acdcallinformation` acdcallinformation
INNER JOIN skillinfo ON skillinfo.pkey = acdcallinformation.skillid
WHERE DATEOFCALL = DATE(NOW())
GROUP BY skill;发布于 2013-02-08 00:36:22
尝试此查询。整个查询只是一个猜测,但如果您提供一些数据,结果会更好。另外,我已经使用id作为主键,你需要用你自己的键替换它。避免使用子查询,而使用连接,它们的速度要快得多。下面是查询。
SELECT
IF(l.LDifference IS NULL,0,r.RDifference) AS 'Lost Calls',
IF(COUNT(acdcallinformation.idleonqueue) IS NULL , 0 , COUNT(acdcallinformation.idleonqueue))AS 'Total Calls',
IF(COUNT(acdcallinformation.`ANSWERTIME`) IS NULL,0,COUNT(acdcallinformation.`ANSWERTIME`))AS 'Answered',
(SELECT skillinfo.skillname FROM skillinfo WHERE skillinfo.pkey = acdcallinformation.skillid) AS Skill,
SEC_TO_TIME(AVG(TIME_TO_SEC(a.answertime)- TIME_TO_SEC(a.firstringonqueue))) AS 'Average Answer Time',
SEC_TO_TIME(AVG(TIME_TO_SEC(a.IDLEONQUEUE) - TIME_TO_SEC(a.answertime))) AS 'Average Talk Time'
FROM acdcallinformation as a
INNER JOIN(
SELECT
(COUNT(ag.`PKEY`) - COUNT(ag.`ANSWERTIME`)) as `LDifference`
FROM acdcallinformation ag
WHERE (ag.`COMPLETED`) = 1 AND answertime IS NULL AND DATEofcall = DATE(NOW()) AND ag.skillid = acdcallinformation.skillid
) as l ON l.id = a.id
INNER JOIN(
SELECT (COUNT(ag.`PKEY`) - COUNT(ag.`ANSWERTIME`)) as `RDifference`
FROM acdcallinformation ag
WHERE (ag.`COMPLETED`) = 1 AND answertime IS NULL AND DATEofcall= DATE(NOW()) AND ag.skillid = acdcallinformation.skillid
) as r ON r.id = a.id
WHERE a.DATEOFCALL = DATE(NOW())
GROUP BY skill;https://stackoverflow.com/questions/14755666
复制相似问题