2011-07-20 222 views
-1

SQL:提高SQL查询性能

select distinct DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) as Date, 
(select count(*) from Raw_Mats A where DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0)=DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0)) as Total, 
(select count(*) from Raw_Mats B where DateAdd(Day, DateDiff(Day, 0, B.Receive_date), 0)=DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) and B.status='Solved') as Delivered, 
(select count(*) from Raw_Mats C where DateAdd(Day, DateDiff(Day, 0, C.Receive_date), 0)=DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) and C.status='Pending') as UnDelivered 
from Raw_Mats m where m.Receive_date between '2011-07-01' and '2011-07-21' 

如何增加上述查询的性能。它需要44秒。想使之小于10秒

感谢

+3

请编辑你的问题。标记你的代码 – drupality

+2

请也描述你的模式。 – rkaregaran

+1

你正在使用哪个数据库? MySQL的? SQLSEVER? – Bohemian

回答

3

你对Receive_datestatus有索引吗? (未在每个索引,合并的)

另外:

  • 你必须有4个接触中,这意味着该查询将缩放表至少O(4N)。 通过使用COUNT(CASE),你可以删除DeliveredUnDelivered子查询
  • 不需要简单的计数子查询要么
  • 你需要GROUP BY。根据您的个人是一个变通为
  • 之间>=<=这是不正确的,通常与时间日期

我在这里使用子查询的清晰度,但它并不重要:

select 
    DateOnly as Date, 
    COUNT(*) AS Total, 
    COUNT(CASE WHEN status='Solved' THEN 1 END) AS Delivered, 
    COUNT(CASE WHEN status='Pending' THEN 1 END) AS UnDelivered 
from 
    (
    SELECT 
     DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) as DateOnly, 
     status 
    FROM 
     Raw_Mats 
    WHERE 
     Receive_date >= '2011-07-01' AND Receive_date < '2011-07-21' 
    ) T 
GROUP BY 
    DateOnly 

编辑,无子查询。

我开始用一个子查询,因为我认为这是更复杂的超过预期,并没有打扰到它...

select 
    DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) as Date, 
    COUNT(*) AS Total, 
    COUNT(CASE WHEN status='Solved' THEN 1 END) AS Delivered, 
    COUNT(CASE WHEN status='Pending' THEN 1 END) AS UnDelivered 
from 
    Raw_Mats 
WHERE 
    Receive_date >= '2011-07-01' AND Receive_date < '2011-07-21' 
GROUP BY 
    DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) 
+0

有一个问题:你为什么使用子查询而不是查询表? – niktrs

+0

@niktrs:更清晰 – gbn

0

分而治之:只要尽你的SQL作为一个单独的语句的每个部分,你会发现这部分是缓慢的。如果你有子选择和函数,那么很有可能,服务器需要临时表来执行选择,如果你没有足够的内存(或者一个大的数据集或者配置你的sql服务器来这样做),这个临时对象被交换到磁盘,这也使它变慢。

0

太多的子查询的人!摆脱其中的一些,它会有所帮助。你也不应该在你的sqls中使用双方的函数。

例如:

where DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0)= 
       DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) 

在这种特殊情况下数据库引擎将不得不通过所有行评估DateDiff(Day, 0, A.Receive_date) and DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0)然后用右手边这也是一个比较功能!这简直是​​一场灾难。

另外,你有索引Receive_date?如果没有添加它。