调优 SQL 查询:在同一张表上具有聚合函数的子查询

Posted

技术标签:

【中文标题】调优 SQL 查询:在同一张表上具有聚合函数的子查询【英文标题】:Tuning SQL query : subquery with aggregate function on the same table 【发布时间】:2018-05-07 13:42:46 【问题描述】:

以下查询大约需要 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

谢谢

【问题讨论】:

你使用的是哪个数据库?? 一些样本数据会很好。马上,如果你能取消那些相关的子查询,你可能会更好。 @TimBiegeleisen 谢谢 .. 我没有注意到 .. @scaisEdge,我正在使用 sybase DISTINCTSELECT DISTINCT 的一部分,适用于整个选定行。跳过那些多余的括号,写select distinct t1.code, t1.ent, ... 让事情更清楚。 【参考方案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 for table2 在认知上是不和谐的,尽管我知道这些都是虚构的。 not exists(尤其是使用正确的索引)应该比聚合子查询更快。 索引将满足where 子句,减少过滤所需的数据。 select distinct 是一个声明。 distinct 不是函数,所以括号什么都不做。 从不FROM 子句中使用逗号。 始终使用正确、明确、标准的 JOIN 语法。

【讨论】:

table1 索引有倒序字段的任何特殊原因? 太棒了!!谢谢。我刚刚在第一个选择中添加了 distinct,它花了 2.5 秒 @JuanCarlosOropeza 。 . .我的理由反过来了。索引现在更有意义了吗? 不,我的意思是为什么一个有dat,code而另一个有code,dat

以上是关于调优 SQL 查询:在同一张表上具有聚合函数的子查询的主要内容,如果未能解决你的问题,请参考以下文章

更新查询在同一张表上的 Sql 查询死锁

难以在同一张表上创建更新总计查询

同一张表上的多个连接,在一个查询中计数

无法在同一张表上查询和更新的问题解决方法

聚合函数以提取更多记录字段数据

如何在一张表中添加两个查询?