简体   繁体   English

提高 SQL 查询性能

[英]Increase SQL Query Performance

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'

How to increase the performance of the above query.如何提高上述查询的性能。 It is taking 44 secs.它需要 44 秒。 wanna make it less than 10 secs想让它少于 10 秒

Thanks谢谢

Do you have an index on both Receive_date and status ?您对Receive_datestatus都有索引吗? (not an index on each, combined) (不是每个的索引,合并)

Also:还:

  • You have have 4 touches in the table which means the query will scale at least O(4n).您在表中有 4 次触摸,这意味着查询将至少扩展 O(4n)。 By using COUNT(CASE) you can remove Delivered and UnDelivered subqueries通过使用 COUNT(CASE) 你可以删除DeliveredUnDelivered子查询
  • The simple count subquery isn't needed either也不需要简单的计数子查询
  • You need GROUP BY.你需要 GROUP BY。 YOur DISTINCT is a work around for that YOUR DISTINCT 是解决这个问题的方法
  • BETWEEN is >= and <= which isn't the usually correct for dates with times BETWEEN 是>=<=这对于有时间的日期通常不正确

I've used a subquery here for clarity but it doesn't matter:为了清楚起见,我在这里使用了子查询,但这没关系:

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

Edit, without subquery.编辑,没有子查询。

I started with a subquery because I thought it's be more complex than expected and didn't bother taking it out...我从一个子查询开始,因为我认为它比预期的更复杂,并且没有费心把它拿出来......

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)

Divide and conquer: Just try each part of your sql as a separate statement and you'll find out which part is slow.分而治之:只需将 sql 的每个部分作为单独的语句尝试,您就会发现哪个部分慢。 If you have sub-selects and functions there is a good chance, that the server need temp-tables to perform the select, if you haven't got enough memory (or a large dataset or configured your sql server to do so), this temp-objects are swapped to disk, which makes it slow too.如果您有子选择和功能,那么服务器很可能需要临时表来执行 select,如果您没有足够的 memory(或大型数据集或将您的 ZAC5C74B64B4B8352AF2F181 配置为服务器)临时对象被交换到磁盘,这也使它变慢。

Too many sub queries man.太多子查询的人。 Get rid of some of them and it will help.摆脱其中的一些,它会有所帮助。 Also you should not use functions on both sides in your sqls.此外,您不应该在 sql 的两边都使用函数。

For example:例如:

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

In this specific case the db engine will have to go through all the rows to evaluate DateDiff(Day, 0, A.Receive_date) and DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0) then compare it with the right hand side which also is a function.在这种特定情况下,数据库引擎必须通过所有行 go 来评估DateDiff(Day, 0, A.Receive_date) and DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0)然后将其与右手边也是 function。 This simply is a disaster.这简直就是一场灾难。

Also, do you have indexes on Receive_date ?另外,您在Receive_date上有索引吗? If not add it.如果没有添加它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM