【问题标题】:How to reduce "sort" cost (t-SQL)如何降低“排序”成本(t-SQL)
【发布时间】:2015-12-07 22:21:23
【问题描述】:

我有一个 T-SQL 查询。在 Microsoft SQL Server Management Studio (SSMS) 中使用 Display Estimated Execution Plan,我发现最后一个 sort 操作消耗了总成本的 83%。

奇怪的是,当我删除WHEREORDER BY 时,它只会增加sort 的成本。所以我的问题是:还有什么可以增加这个链接的成本?

查询

SELECT                                                                  
o.boardordrenr      as 'SenDX Board Run', 
bo.boardordrerunnr  as 'RMED Board Run',                                                       
o.ordrerunnr        as 'Dispensing Run',                                                                             
o.ordreidnr         as 'Board ID', 
o.boardnr           as 'Board No.',
ba.raekkenr         as 'Row',       
ba.arraynr          as 'Array',
s0.sensor           as 'Sensor',
ks.diameter         as 'Cavity Diameter',
ks.kavitet_dybde    as 'Cavity Depth',
ms1.tykkelse        as 'CA Thickness',
ms1.membrane_Stdev  as 'CA Std. Dev.',
s1.void_procent     as 'CA Void Fraction',
s1.skannet_dt       as 'CA Scan Date',
ms2.tykkelse        as 'OM Thickness',
ms2.membrane_Stdev  as 'OM Std. Dev.',
s2.void_procent     as 'OM Void Fraction',
s2.skannet_dt       as 'OM Scan Date',
ft_sc_par.vaerdi    as 'Sens'


FROM 
boardordre bo                                                                        
INNER JOIN ordre o          ON bo.boardordrenr = o.boardordrenr AND DATEDIFF(MONTH, o.oprettet_dt, GETDATE()) < 3 AND o.ordrevarenr = 932029                                                 
INNER JOIN boardarray ba    ON ba.ordrenr = o.ordrenr    
LEFT JOIN sensorkassette sc ON sc.boardarraynr_bund = ba.boardarraynr

LEFT JOIN skanning s0           ON s0.boardarraynr = ba.boardarraynr AND s0.overflade_index = 0 AND s0.sensor in ('Glu','Lac')  -- Cavity
LEFT JOIN skanning s1           ON s1.boardarraynr = ba.boardarraynr AND s1.overflade_index = 1 AND s1.sensor = s0.sensor       -- CA Membrane
LEFT JOIN skanning s2           ON s2.boardarraynr = ba.boardarraynr AND s2.overflade_index = 2 AND s2.sensor = s0.sensor       -- Outer Membrane

LEFT JOIN kavitetskanning ks    ON ks.skanningnr  = s0.skanningnr    
LEFT JOIN membranskanning ms1   ON ms1.skanningnr = s1.skanningnr  
LEFT JOIN membranskanning ms2   ON ms2.skanningnr = s2.skanningnr AND (ms2.membrannavn = 'YM_UDV' OR ms2.membrannavn = 'YM')

LEFT JOIN funktionstest_sc ft_sc            ON ft_sc.sensorkassette_chipnr = sc.sensorkassette_chipnr
LEFT JOIN funktionstest_sc_param ft_sc_par  ON ft_sc_par.funktionstest_sc_nr = ft_sc.funktionstest_sc_nr AND ft_sc_par.sensor = s0.sensor AND ft_sc_par.parameter = 'Sens'

执行计划(链接)

https://dl.dropboxusercontent.com/u/5957600/sql_execution_plan_actual.sqlplan

【问题讨论】:

  • 你为什么要坚持改进排序?发布实际的执行计划,以便我们可以将查询作为一个整体进行优化。
  • 那么,您要排序的那些列是否已编入索引
  • distinct 会带来很大的成本。
  • 在查询计划中寻找“胖管道”——这些表示可能是工作来源的大型中间结果。此外 - 可能会在查看实际查询计划而不是估计计划时获得更多线索。有时会很不一样。
  • 是的,连接时缺少索引是个问题。在 where 中的 so 将左连接变为常规连接。

标签: sql sql-server tsql sorting ssms


【解决方案1】:

在所有连接条件上放置索引

s0.sensor in ('Glu','Lac') 把它变成了一个内连接

试试这个

FROM 
    boardordre bo 
INNER JOIN 
    ordre o ON bo.boardordrenr = o.boardordrenr 
            AND o.ordrevarenr = 932029  
            AND DATEDIFF(MONTH, o.oprettet_dt, GETDATE()) < 3 
INNER JOIN 
    boardarray ba ON ba.ordrenr = o.ordrenr    
LEFT JOIN 
    sensorkassette sc ON sc.boardarraynr_bund = ba.boardarraynr
INNER JOIN 
    skanning s0 ON s0.boardarraynr = ba.boardarraynr 
                AND s0.overflade_index = 0 -- Cavity 
                AND s0.sensor in ('Glu','Lac')

删除位置

【讨论】:

  • 去掉WHERE 大约将查询的运行时间减半。谢谢你的建议。我的印象是,在JOIN 中使用条件还是在最后使用WHERE 并不重要
【解决方案2】:

你做了一个 distinct,为了有效地做 distinct,SQL Server 可能需要先做一个排序。你的执行计划会给你你需要知道的答案。在这种情况下,索引肯定会有所帮助。

【讨论】:

  • 您可能正在做某事。删除DISTINCT 将成本从Sort 切换到Parallelism。然而,总执行时间没有改变。
猜你喜欢
  • 2022-01-16
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-01
相关资源
最近更新 更多