T-SQL查询优化

T-SQL查询优化,sql,sql-server,performance,correlated-subquery,Sql,Sql Server,Performance,Correlated Subquery,我有一个性能非常差的查询。在生产数据库中,有数千万行数据 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.co

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

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
我已经尝试解决索引、连接和CTE的性能问题。但是由于使用了聚合函数和相关子查询,因此我没有发现任何可以提高性能的方法

有人知道我该如何改进吗

查询计划:


没有查询计划,而且由于您所有的列名都是通用的,而且我不确定您想要生成什么,所以我无法告诉您哪些内容是必需的,哪些内容不是必需的。但这里有一些一般性的建议:

您对相关子查询的亲和力可能并没有帮助,谓词或查询组合在一起的事实也没有帮助。很可能您的过程有时或总是进行全表扫描,因为它不知道您可能会有什么类型的输入

首先,我建议将不同的OR'd案例分为各自的if/else分支。这样,每个语句都可以得到一个查询计划,该计划的作用域是它正在做的事情


我还想看看你是否可以分几个步骤来做。也许可以对你的大表进行一次有效的搜索,然后在一个临时表或其他东西中进行搜索,然后在更小的、孤立的集合上进行操作。

但是,这当然不会编译,如果Colxxx字段的索引正确,那么您可以通过聚合总和和标志并执行其中的一些条件(而不是逐行执行)来提高速度

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的错误计数,其中col4=0,或者您是说col4=tab1中所有记录的计数???

附加查询计划?生成查询计划,然后将XML版本粘贴到并在此处共享链接。这将有助于分析如何改进查询。这是一个相当复杂的查询。我想在所有这些查找和/或条件下,您无法更快地实现这一点。当然,tab1col2、tab1col4和tab3col1上应该有索引。通过将tab1col2上的索引替换为tab1col2、col3、col4、col5、col1上的覆盖索引,您可以更快地实现这一点。您能解释一下查询应该做什么吗?样本数据和期望的结果会有所帮助。请记住,p或q和r被解释为p或q,rI同意语句select count*FROM tbl1为p1,其中tab1.col4=p1.col4=0的计算结果必须始终为false。始终至少会有一条记录。如果col4为空,则select count…=0将为真简言之,语句select count*FROM tab1 AS p1,其中tab1.col4=p1.col4=0类似于指定的相反方式,或者tab1.col4为空,因此我们得出结论,select count…=0可以替换为tab1.col4为空?抱歉前面的评论。应该是空的。