代码之家  ›  专栏  ›  技术社区  ›  david hale

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

  •  0
  • david hale  · 技术社区  · 7 年前

    下面的查询大约需要30秒才能给出结果。 表1包含约2000万条管线 表2包含约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 回复  |  直到 7 年前
        1
  •  1
  •   Gordon Linoff    7 年前

    这是你的疑问,写得更合理:

     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) --对于where
    • table1(code, dat) --对于子查询
    • table2(cod, lib, typ) --对于连接

    备注:

    • 表别名应该有意义。 t3 对于 table2 是认知上的不和谐,尽管我知道这些是虚构的名字。
    • not exists (尤其是使用正确的索引)应该比聚合子查询更快。
    • 索引将满足 where 子句,减少筛选所需的数据。
    • select distinct 是一个声明。 distinct 不是函数,因此括号不起任何作用。
    • 从不 在中使用逗号 FROM 条款 总是 使用适当、明确、标准 JOIN 语法。