调优 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,我正在使用 sybaseDISTINCT
是SELECT 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 查询:在同一张表上具有聚合函数的子查询的主要内容,如果未能解决你的问题,请参考以下文章