1.建立表 Staffhtml
CREATE TABLE [dbo].[Staff]( [ID] [int] IDENTITY(1,1) NOT NULL, [Name] [varchar](50) NULL, [Sex] [varchar](50) NULL, [Department] [varchar](50) NULL, [Money] [int] NULL, [CreateDate] [datetime] NULL ) ON [PRIMARY] GO
2.爲Staff表填充數據函數
INSERT INTO [dbo].[Staff]([Name],[Sex],[Department],[Money],[CreateDate]) SELECT 'Name1','男','技術部',3000,'2011-11-12' UNION ALL SELECT 'Name2','男','工程部',4000,'2013-11-12' UNION ALL SELECT 'Name3','女','工程部',3000,'2013-11-12' UNION ALL SELECT 'Name4','女','技術部',5000,'2012-11-12' UNION ALL SELECT 'Name5','女','技術部',6000,'2011-11-12' UNION ALL SELECT 'Name6','女','技術部',4000,'2013-11-12' UNION ALL SELECT 'Name7','女','技術部',5000,'2012-11-12' UNION ALL SELECT 'Name8','男','工程部',3000,'2012-11-12' UNION ALL SELECT 'Name9','男','工程部',6000,'2011-11-12' UNION ALL SELECT 'Name10','男','工程部',3000,'2011-11-12' UNION ALL SELECT 'Name11','男','技術部',3000,'2011-11-12'
GROUP BY 分組查詢, 通常和聚合函數配合使用性能
SELECT [DEPARTMENT],SEX, COUNT(1) FROM DBO.[STAFF] GROUP BY SEX, [DEPARTMENT]
該段SQL是用於查詢 某個部門下的男女員工數量 其數據結果以下
spa
開銷比較大 code
GROUPING SETShtm
使用 GROUPING SETS 的 GROUP BY 子句能夠生成一個等效於由多個簡單 GROUP BY 子句的 UNION ALL 生成的結果集,而且其效率比 GROUP BY 要高,SQL Server 2008引入。 blog
1.使用GROUP BY 子句的 UNION ALL 來統計 Staff 表中的性別、部門、薪資、入職年份內存
SET STATISTICS IO ON SET STATISTICS TIME ON SELECT N'總人數' ,'',COUNT(0) FROM [DBO].[STAFF] UNION ALL SELECT N'按性別劃分', SEX,COUNT(0) FROM [DBO].[STAFF] GROUP BY SEX UNION ALL SELECT N'按部門統計',[DEPARTMENT],COUNT(0) FROM [DBO].[STAFF] GROUP BY [DEPARTMENT] UNION ALL SELECT N'按薪資統計',CONVERT(VARCHAR(10),[MONEY]),COUNT(0) FROM [DBO].[STAFF] GROUP BY [MONEY] UNION ALL SELECT N'按入職年份',CONVERT(VARCHAR(10),YEAR([CREATEDATE])),COUNT(0) FROM [DBO].[STAFF] GROUP BY YEAR([CREATEDATE])
2.換成GROUPING SETS的寫法class
SET STATISTICS IO ON SET STATISTICS TIME ON GO SELECT (CASE WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=15 THEN N'總人數' WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=7 THEN N'按性別劃分' WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=11 THEN N'按部門統計' WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=13 THEN N'按薪資統計' WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=14 THEN N'按入職年份' END ), (CASE WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=15 THEN '' WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=7 THEN SEX WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=11 THEN [DEPARTMENT] WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=13 THEN CONVERT(VARCHAR(10),[MONEY]) WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=14 THEN CONVERT(VARCHAR(10),YEAR([CREATEDATE])) END ) , COUNT(1) FROM DBO.[STAFF] GROUP BY GROUPING SETS (SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]),())
從上述結果中能夠看出,採用UNION ALL 是屢次掃描表,並將掃描後的查詢結果進行組合操做,會增長IO開銷,減小CPU和內存開銷。效率
採用GROUPING SETS 是一次性讀取全部數據,並在內存中進行聚合操做生成結果,減小IO開銷,對CPU和內存消耗增長。但GROUPING SETS 在多列分組時,其性能會比group by高。
這裏掃描四次是由於我 GROUP BY GROUPING SETS (SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]),()) 了四列
ROLLUP與CUBE
ROLLUP與CUBE 按必定的規則產生多種分組,而後按各類分組統計數據
ROLLUP與CUBE 區別:
CUBE 會對全部的分組字段進行統計,而後合計。
SELECT CASE WHEN (GROUPING(SEX) = 1) THEN '統計-ROLLUP' ELSE ISNULL(SEX, 'UNKNOWN') END AS SEX , COUNT(0) FROM DBO.[STAFF] GROUP BY SEX WITH ROLLUP SELECT CASE WHEN (GROUPING(SEX) = 1) THEN '統計-CUBE' ELSE ISNULL(SEX, 'UNKNOWN') END AS SEX , COUNT(0) FROM DBO.[STAFF] GROUP BY SEX WITH CUBE
SELECT CASE WHEN (GROUPING(SEX) = 1) THEN '統計-ROLLUP' ELSE ISNULL(SEX, 'UNKNOWN') END AS SEX , CASE WHEN (GROUPING([DEPARTMENT]) = 1) THEN '統計-ROLLUP' ELSE ISNULL([DEPARTMENT], 'UNKNOWN') END AS [DEPARTMENT], COUNT(0) FROM DBO.[STAFF] GROUP BY SEX,[DEPARTMENT] WITH ROLLUP SELECT CASE WHEN (GROUPING(SEX) = 1) THEN '統計-CUBE' ELSE ISNULL(SEX, 'UNKNOWN') END AS SEX , CASE WHEN (GROUPING([DEPARTMENT]) = 1) THEN '統計-CUBE' ELSE ISNULL([DEPARTMENT], 'UNKNOWN') END AS [DEPARTMENT], COUNT(0) FROM DBO.[STAFF] GROUP BY SEX,[DEPARTMENT] WITH CUBE
能夠看出 使用 ROLLUP 會先統計分組下的,而後在對GROUP BY的第一列字段進行統計,最後計算總數,而 CUBE 則是先分組統計,而後統計GRUOP BY 的每一個字段,最後進行彙總。
http://www.cnblogs.com/woxpp/p/4688715.html