2011-10-21 40 views
1

我可以重复使用一个复杂的条款选择在哪里by子句不同的群体?不同组通过在相同的查询(选择/凡)

我在做什么:

(Select X, Count(*) From [Big where clause with many tables] Group By X) 
Union All 
(Select Y, Count(*) From [Big where clause with many tables] Group By Y) 

我怎样才能optmise呢?

我使用的是SQL Server 2008中,这将大大函数内部,但可能是一个存储过程。

回答

5
WITH basequery AS (Select * From [Big where clause with many tables]) 
SELECT X, COUNT(*) FROM basequery GROUP BY X 
UNION ALL 
SELECT Y, COUNT(*) FROM basequery GROUP BY Y; 

CTE是为这样的情况而制造的。你可以评估(特别是如果有相对较少的x,y组)

+0

不错..只是换名/定义:)谢谢 – ariel

+2

@ariel不知道是否“减少昂贵通货膨胀”你指的是你的问题的代码或性能?作为性能优化,这种效应将是中性的。它将重用查询定义而不是工作。CTE仍会得到两次评估,该计划可能与您的原始查询相同。 –

+0

是的,看到在执行计划 – ariel

2

一个办法是给自己物化中间结果为@table#temp表,则只是从SELECT(一#temp表会更好,因为你可以设置比下面的更好指标,它允许填充它被并行化,但这些不具备的功能)

DECLARE @T TABLE 
(
X int, 
Y int, 
Cnt int, 
UNIQUE(X,Y,Cnt), /*Cnt just included to make index covering*/ 
UNIQUE(Y,X,Cnt) 
) 

INSERT INTO @T 
Select X, Y, Count(*) 
From [Big where clause with many tables] 
Group By X, Y 


SELECT X, SUM(Cnt) 
FROM @T 
GROUP BY X 
UNION ALL 
SELECT Y, SUM(Cnt) 
FROM @T 
GROUP BY Y 
0

创建视图的选择查询

CREATE VIEW SomeView 
AS 
    Select X, Y, Count(*) AS C From [Big where clause with many tables] 

然后使用视图:

Select X, C FROM SomeView GROUP BY X 
2

SQL Server 2008中推出了GROUPING SETS()这似乎正是你所追求的。由他人提出的解决方案UNION现在可以轻松地与一个单一的选择来替换GROUPING SETS

基本上,您使用的是这样的:

SELECT A, B, C 
FROM … 
WHERE … 
GROUP BY GROUPING SETS ((A), (B), (C)) 

这相当于

SELECT A, NULL, NULL, … 
FROM … 
WHERE … 
GROUP BY A 

UNION ALL 

SELECT NULL, B, NULL, … 
FROM … 
WHERE … 
GROUP BY B 

UNION ALL 

SELECT NULL, NULL, C, … 
FROM … 
WHERE … 
GROUP BY C 

所以,您的查询可能是这样的:

SELECT X, Y, COUNT(*) 
FROM your complex joins and filters 
GROUP BY GROUPING SETS ((X), (Y)) 

或者这样:

SELECT 
    CASE WHEN X IS NULL THEN 'Y' ELSE 'X' END AS ObjType 
    CASE WHEN X IS NULL THEN Y ELSE X END AS Obj, 
    COUNT(*) 
FROM your complex joins and filters 
GROUP BY GROUPING SETS ((X), (Y)) 

第二个假定X不能为NULL。

参考文献: