调优SQL查询:在同一个表上使用聚合函数的子查询

时间:2018-05-07 13:42:47

标签: sql subquery aggregate-functions sybase query-performance

以下查询大约需要30秒才能显示结果。 table1包含~20m行 table2包含~10000行

我试图找到改善表现的方法。有什么想法吗?

declare @PreviousMonthDate datetime 
select @PreviousMonthDate = (SELECT DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()) - 1, '19000101') as [PreviousMonthDate])

     select  
 distinct(t1.code), t1.ent, t3.lib, t3.typ from table1 t1, table2 t3
     where (select min(t2.dat) from table1 t2 where   t2.code=t1.code) >@PreviousMonthDate
and t1.ent in ('XXX')
and t1.code=t3.cod
and t1.dat>@PreviousMonthDate

谢谢

1 个答案:

答案 0 :(得分:1)

这是你的查询,写得更明智:

 select t1.code, t1.ent, t2.lib, t2.typ
 from table1 t1 join
      table2 t2
      on t1.code = t2.cod
 where not exists (select 1
                   from table1 tt1
                   where tt1.code = t1.code and
                         tt1.dat <= @PreviousMonthDate 
                  ) and
       t1.ent = 'XXX' and 
       t1.dat > @PreviousMonthDate;

对于此查询,您需要以下索引:

  • table1(ent, dat, code) - 适用于哪里
  • table1(code, dat) - 用于子查询
  • table2(cod, lib, typ) - 用于加入

注意:

  • 表别名应该有意义。 t3的{​​{1}}在认知上是不协调的,即使我知道这些是由名字组成的。
  • table2(特别是使用正确的索引)应该比聚合子查询更快。
  • 索引将满足not exists子句,减少过滤所需的数据。
  • where是一个声明。 select distinct不是函数,因此括号不执行任何操作。
  • 从不distinct子句中使用逗号。 始终使用正确,明确,标准的FROM语法。