具有cte和rownumber性能

时间:2016-03-09 08:27:00

标签: sql sql-server

我有一个包含超过3.5亿的桌子(销售)。我尝试执行以下查询,但花了很长时间

 select t1.[datecol],t1.[Prix de vente TTC],t1.Quantité 
      from [Vente] t1
      inner join (select distinct [datecol],[Code Article],[Code Structure],[Code Site],
      row_number() over(Partition by  [Code Article],[Code Structure],[Code Site] order by [datecol]desc ) as rn

      from (select distinct  [datecol],[Code Article],[Code Structure],[Code Site]
           from [Vente] t2
            where promo = 0
                  and ([Code Article] is not null) 
                  and ([Code Structure] is not null) 
                  and ([Prix de Revient] is not null)
    )g
          ) a
           on a.datecol=t1.datecol
            and t1.[Code Article] = a.[Code Article]
            and t1.[Code Structure]=a.[Code Structure]
            and t1.[Code Site]=a.[Code Site]
            where  promo = 0
            and (t1.[Code Article] is not null) and (t1.[Code Structure] is not null) and ([Prix de Revient] is not null ) 
            and
              rn <= 28

执行计划

enter image description here

1 个答案:

答案 0 :(得分:1)

嗯,这是row_number的价格。它不是在搜索 - 它正在排序和构建一个新列。这就像你在说“你什么都不知道,sql server!让我告诉你你的日期以及如何计算desc顺序。这个日期与第一,这是两个,......”

我看到以前的帖子有计划,提到了一些索引,所以试试吧(请发布计划图片):

select t1.[datecol],t1.[Prix de vente TTC],t1.Quantité 
from [Vente] t1
outer apply
(
  select top 28 distinct t2.[datecol]
  from [Vente] t2
  where t2.[Code Article] = t1.[Code Article]
    and t2.[Code Structure]=t1.[Code Structure]
    and t2.[Code Site]=t1.[Code Site]
  order by t2.[datecol] desc
) t2
where t1.promo = 0
  and (t1.[Code Article] is not null)
  and (t1.[Code Structure] is not null) 
  and (t1.[Prix de Revient] is not null ) 
  and t1.datecol = t2.datecol

我不确定你的最终目标和实际要求(关于那些“28天”)。另一种方法是首先找出天数,将临时表存储在临时表中,然后加入。

正如我已经提到的,我不知道要求所以不能说是否可以通过应用简单的简单过滤器来完成所有任务 where t1.datecol >= dateadd(dd, -28, cast(getdate() as date)) - 但我建议你考虑一下。

但不知何故,我确信您不需要比一年前更早的数据。应用此过滤器,切断您不需要的数据。计算set @startdate = dateadd(yy, -1, getdate())(可能少于一年)并将此过滤器应用于内部和外部查询。这将切断您不需要处理的大量数据。

目前您没有除promo=0和计算日期过滤器之外的任何过滤器,因此您几乎可以处理所有这些350M记录。请应用一些过滤器。想想他们即使没有人提及。您肯定不需要太旧的数据,您可能不需要price=0quantity=0的数据,可能是其他内容。切断。