T-SQL查询优化

问题描述 投票:-2回答:2

我有一个性能很差的查询。在生产数据库中,有数千万行数据。

SELECT 
    (SELECT MIN(CASE WHEN tab1.col1 = 0 THEN 0 ELSE 1 END) 
     FROM tab1 
     WHERE tab1.col2 = tab2.col2
       AND (tab2.col1 <> 1
            OR (SELECT COUNT(*) FROM tab1 AS p1 WHERE tab1.col4 = p1.col4) = 0)
       AND (tab1.col3 = 1 OR tab2.col1 = 0
            AND ISNULL((SELECT SUM(tab3.col1) FROM tab3 WHERE tab3.col1 = tab2.col2), 0) < tab1.col5)) col_alias
FROM 
    tab2

我已经尝试用索引,JOIN和CTE解决性能问题。但由于使用了聚合函数和相关子查询,因此我没有改进性能的任何内容。

有没有人有任何想法我怎么做才能改善这个?

查询计划:

https://www.brentozar.com/pastetheplan/?id=SJSUd1pOX

enter image description here

sql sql-server performance correlated-subquery
2个回答
2
投票

如果没有查询计划,并且由于您的所有列名都是通用的,并且我不确定您要创建的是什么,我无法告诉您在那里需要或不需要的内容。但这里有一些一般的建议:

你对相关子查询的亲和力可能没有帮助,也不是你的谓词OR在一起的事实。您的程序很可能有时或总是进行全表扫描,因为它不知道您可能具有哪种输入。

首先,我建议将不同的OR案例分解为自己的if / else分支。这样,每个语句都可以获得一个范围为它正在做什么的查询计划。

我还会看看你是否可以通过几个步骤完成这项工作。也许对你的大桌子进行一次有效的高效搜索,然后在临时表或其他东西中进行操作,然后在更小,更孤立的集合上进行操作。


0
投票

这当然不会编译,但是,如果Colxxx字段被正确编入索引,那么你可以通过聚合sums和flags并在那里执行一些条件而不是逐行来获得速度。

SELECT
    MinFlag = MIN(MinFlag)
FROM
(
    SELECT 
        Table1Column2 = tab1.Col2,
        MinFlag = CASE WHEN tab1.col1 = 0 THEN 0 ELSE 1 END,
        SumTable3Column1= tab3.col1 ,
        ConditionThreeFlag = CASE WHEN tab1.col3 = 1 OR tab2.col1 = 0 THEN 1 ELSE 0 END,
        Tabel1Column5 = tab1.col5
    FROM 
        tab2
        INNER JOIN tab1 ON tab1.col2 = tab2.col2 
        LEFT OUTER JOIN tab3 ON tab3.col1 = tab2.col2
    WHERE 
        (tab2.col1 <> 1 OR tab1.col4 IS NULL)

)AS X
GROUP BY
        X.Table1Column2 
HAVING 
    ((MAX(ConditionThreeFlag) = 1) AND (SUM(SumTable3Column1) < MAX(Tabel1Column5)))

编辑:我迷失在这里,我想了一下,并决定这将永远是假的(所有col4的数量再次加入col4,其中count == 0)或者你在说col4 = tab1中所有记录的计数? ?

© www.soinside.com 2019 - 2024. All rights reserved.