有没有办法优化下面的查询?
SELECT
DATE_FORMAT(a.duedate,'%d-%b-%y') AS dte,
duedate,
SUM(CASE WHEN (typeofnotice='ddat' AND STATUS='open') THEN 1 ELSE 0 END) AS 'DDatOpen',
SUM(CASE WHEN (typeofnotice='ddat' AND STATUS='closed') THEN 1 ELSE 0 END) AS 'DDatClosed',
SUM(CASE WHEN (b.action='tagunchanged' AND STATUS='closed') THEN 1 ELSE 0 END) AS 'DDatUnchanged',
SUM(CASE WHEN (typeofnotice='rss' AND validindicator IS NULL AND STATUS='open') THEN 1 ELSE 0 END) AS 'RSSValidation',
SUM(CASE WHEN (typeofnotice='rss' AND validindicator=1 AND STATUS='open') THEN 1 ELSE 0 END) AS 'RSSValidOpen',
SUM(CASE WHEN (typeofnotice='rss' AND validindicator=1 AND STATUS='closed') THEN 1 ELSE 0 END) AS 'RSSValidClosed',
SUM(CASE WHEN (typeofnotice='rss' AND validindicator=0) THEN 1 ELSE 0 END) AS 'RSSInvalid',
SUM(CASE WHEN (typeofnotice='copernic' AND validindicator IS NULL AND STATUS='open') THEN 1 ELSE 0 END) AS 'CopernicValidation',
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=1 AND validindicator=1 AND STATUS='open') THEN 1 ELSE 0 END) AS 'CopernicValidAwardOpen',
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=1 AND validindicator=1 AND STATUS='closed') THEN 1 ELSE 0 END) AS 'CopernicValidAwardClosed',
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=1 AND validindicator=0) THEN 1 ELSE 0 END) AS 'CopernicInvalidAward',
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=0 AND validindicator=1 AND STATUS='open') THEN 1 ELSE 0 END) AS 'CopernicOpportunityValidOpen',
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=0 AND validindicator=1 AND STATUS='closed') THEN 1 ELSE 0 END) AS 'CopernicOpportunityValidClosed',
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=0 AND validindicator=0) THEN 1 ELSE 0 END) AS 'CopernicOpportunityInvalid',
SUM(CASE WHEN (typeofnotice='copernic' AND STATUS='limited') THEN 1 ELSE 0 END) AS 'CopernicLimitation',
SUM(CASE WHEN ((validindicator IS NULL OR validindicator = 1) AND STATUS='open') THEN 1 ELSE 0 END) AS 'TotalNotices',
SUM(CASE WHEN (validindicator=1 AND STATUS='closed') THEN 1 ELSE 0 END) AS 'TotalCompleted',
SUM(CASE WHEN (validindicator=0 AND (typeofnotice='wget' OR typeofnotice='copernic' OR typeofnotice='rss')) THEN 1 ELSE 0 END) AS 'TotalInvalid'
FROM tblNotices AS a LEFT JOIN tblTransactions AS b
ON a.id = b.noticeid WHERE b.noticeid IS NOT NULL
WHERE duedate >= '2011-04-04 00:00:00' AND a.duedate <= '2012-05-08 24:00:00'
GROUP BY dte
ORDER BY dueDate ASC;
tblTransactions有150万行 tblNotices有900k行。
查询运行约1分钟。这是正常的吗?有没有办法优化这个查询?
我认为此处的DATE_FORMAT
功能确实会影响性能..这里有什么提示吗?它运行大约58秒。
答案 0 :(得分:1)
除了SUM(IF())实例之外,查询看起来很简单。
您的查询对事务具有LEFT-JOIN,但是b.noticeID不为null。两者的组合导致双方都需要正常的“JOIN”或“INNER JOIN”。
至于你的Where子句,我会确保你在截止日期有一个简单的索引。你的表显示了一个“MUL”(多键)索引,我会确保截止日期是该键的第一部分,或者至少有一个索引作为第一个字段使用duidate。
接下来,你的小组由。由于您是按截止日期的日期格式进行分组,因此我只会根据duedate(匹配表索引)离开组。无论如何,视觉格式化的字符串将跟随骑行。因为您的Order By也是基于duedate(而不是相当格式化的字符串版本),所以应该很好。
至于查询本身的日期范围...提供的范围内有多少条记录。
的 REVISION 强> 的
您可以利用查询中使用的元素的多部分索引,这样查询就不必实际转到页面数据来查看整个记录中的各个元素。由于数据将成为索引键的一部分,因此查询可以直接使用它,而不需要转到页面。
尝试
上的索引INDEX on ...(DueDate,status,IsAward,TypeOfNotice,ValidIndicator)
另外,为了澄清查询中的alias.fields。有时您明确引用“a”。别名和其他时间,没有别名。对于您或其他人尝试提供帮助后处理查询的其他人。它使得使用适当的别名显式引用所有字段变得更容易,以防止来自哪个表的哪些列的歧义。是的,你在这里提供了你的表格结构,但是未来可以比不断回顾结构更容易。
答案 1 :(得分:0)
嗯,那个
FROM tblNotices AS a LEFT JOIN tblTransactions AS b
ON a.id = b.noticeid WHERE b.noticeid IS NOT NULL
与
相同FROM tblNotices AS a INNER JOIN tblTransactions AS b
ON a.id = b.noticeid
第二个可能更快。
你为什么不通过duedate分组?然后你可以省略DATE_FORMAT(),但我想这只是花生。如果省略它,ORDER BY
也没有必要,因为它与GROUP BY有牵连。
除此之外,你无能为力。