我有一个性能很差的查询。在生产数据库中,有数千万行数据。
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解决性能问题。但由于使用了聚合函数和相关子查询,因此我没有改进性能的任何内容。
有没有人有任何想法我怎么做才能改善这个?
查询计划:
如果没有查询计划,并且由于您的所有列名都是通用的,并且我不确定您要创建的是什么,我无法告诉您在那里需要或不需要的内容。但这里有一些一般的建议:
你对相关子查询的亲和力可能没有帮助,也不是你的谓词OR
在一起的事实。您的程序很可能有时或总是进行全表扫描,因为它不知道您可能具有哪种输入。
首先,我建议将不同的OR
案例分解为自己的if / else分支。这样,每个语句都可以获得一个范围为它正在做什么的查询计划。
我还会看看你是否可以通过几个步骤完成这项工作。也许对你的大桌子进行一次有效的高效搜索,然后在临时表或其他东西中进行操作,然后在更小,更孤立的集合上进行操作。
这当然不会编译,但是,如果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中所有记录的计数? ?