【问题标题】:How to optimise slow SQL query如何优化慢 SQL 查询
【发布时间】:2013-11-25 10:42:17
【问题描述】:

我需要帮助来优化此查询。在存储过程中,这部分执行 1 小时(所有过程需要 2 来执行)。过程适用于大量数据。查询适用于两个临时表。两者都使用索引:

create unique clustered index #cx_tDuguje on #tDuguje (Partija, Referenca, Konto, Valuta, DatumValute)
create nonclustered index #cx_tDuguje_1 on #tDuguje (Partija, Valuta, Referenca, Konto, sIznos)
create unique clustered index #cx_tPotrazuje on #tPotrazuje (Partija, Referenca, Konto, Valuta, DatumValute)
create nonclustered index #cx_tPotrazuje_1 on #tPotrazuje (Partija, Valuta, Referenca, Konto, pIznos)

这是一个查询:

select D.Partija,  
       D.Referenca,  
       D.Konto,  
       D.Valuta,  
       D.DatumValute DatumZad,   
       NULLIF(MAX(COALESCE(P.DatumValute,@NextDay)), ,@NextDay) DatumUpl,  
       MAX(D.DospObaveze) DospObaveze,  
       MAX(D.LimitMatZn) LimitMatZn  
into #dwkKasnjenja_WNT 
from  #tDuguje D  
left join #tPotrazuje P on D.Partija = P.Partija  
                       AND D.Valuta = p.Valuta  
                       AND D.Referenca = p.Referenca   
                       AND D.Konto = P.Konto  
                       and P.pIznos < D.sIznos and D.sIznos <= P.Iznos  
WHERE 1=1  
    AND D.DatumValute IS NOT NULL  
GROUP BY D.Partija, D.Referenca, D.Konto, D.Valuta, D.DatumValute  

我有执行计划,但我无法在此处发布。

【问题讨论】:

    标签: sql sql-server query-optimization sql-execution-plan


    【解决方案1】:

    只是一个想法:如果您被允许这样做,请先尝试更改业务逻辑。

    也许您将结果集限制为仅包含来自有意义的时间点的数据。

    您的帐户数据可以追溯到多长时间?您真的需要包含从 1999 年开始的所有数据吗?

    也许你可以说

    D.DatumValute >= "2010 年 1 月 1 日"

    或类似的,在您的 WHERE 子句中

    这可能会创建一个更小的临时结果集,用于复杂的 JOIN 子句,然后运行得更快。

    如果你不能做到这一点,也许做一个 “select top 1000 ... order by datum desc”查询,它可能运行得更快,然后如果用户确实需要,在第二步中执行运行缓慢的查询。

    【讨论】:

    • 谢谢...已经和客户谈过这件事,并会再次尝试解释,但此时他们想使用存档数据...数以百万计。不过还是谢谢。
    • 然后添加一个暂存数据表(或物化视图),其中两列以预先计算的形式包含间隔列表(我猜这就是...and P.pIznos &lt; D.sIznos and D.sIznos &lt;= P.Iznos 子句正在做的事情)。此数据不应位于临时表中,并且不应在查询完成后丢弃。我猜这个技巧会使查询变得昂贵,因为它迫使引擎顺序计算大量值。
    【解决方案2】:

    很难说没有执行计划或关于每个表中的行数的一些提示。

    替换这个索引

    create nonclustered index #cx_tPotrazuje_1 on #tPotrazuje (Partija, Valuta, Referenca, Konto, pIznos)
    

    通过

    create nonclustered index #cx_tPotrazuje_1 on #tPotrazuje (Partija, Valuta, Referenca, Konto, sIznos, pIznos)
    

    【讨论】:

      【解决方案3】:

      创建索引是一个非常昂贵的过程,有时可能会很慢,这也取决于实例的工作负载和为其创建索引的所涉及的列。

      此外,如果没有执行计划并且不了解索引创建所涉及的列的数据类型,很难说出您需要优化什么。

      例如,Partija, Referenca, Konto, Valuta, DatumValute 列的数据类型不是很清楚。 您应该告诉我们创建索引所涉及的列的数据类型。

      【讨论】:

      • 感谢您的回答。数据类型有:[Partija] [varchar](20)、[Referenca] [varchar](60)、[Konto] [varchar](10)、[Valuta] [varchar](3)、[DatumValute] [varchar] (10) 和 P.pIznos、D.sIznos 和 P.Iznos 是十进制的 (19,2)。而且我无法向您发布执行计划。
      猜你喜欢
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      • 2012-03-05
      • 2016-01-16
      相关资源
      最近更新 更多