综合指数还是单一指数?

时间:2015-02-15 00:16:42

标签: sql-server indexing

在表格中,我有一个Date列,我希望按月和年分组。

我创建了两列:DateMonthDateYear,我已用相应的月份和年份填充它们:

 UPDATE t SET DateMonth = DATEPART(month, Date), DateYear = DATEPART(year, Date)

这样groupby查询就不会使用DATEPART()(sql函数无法利用索引)。

groupby查询如下:

 SELECT DateMonth, DateYear, COUNT(*) AS RowsCount FROM t GROUP BY DateMonth, DateYear

根据这些信息,什么类型的索引可以为以前的groupby查询提供更好的性能?

每列索引:

 CREATE INDEX IX_DateMonth ON t(DateMonth)
 CREATE INDEX IX_DateYear ON t(DateYear)

或一个涵盖两列的索引:

 CREATE INDEX IX_DateMonth_DateYear ON t(DateMonth, DateYear)

1 个答案:

答案 0 :(得分:3)

他们说最好的方法就是实际做到这一点:)

创建了一个包含100,000行的表。

CREATE TABLE DateTable (DateColumn DATETIME , DateMonth INT , DateYear INT)
GO

declare @FromDate date = '1970-01-01'
declare @ToDate date = '2015-12-31'

INSERT INTO DateTable(DateColumn) 
select TOP 100000 dateadd(day,  rand(checksum(newid())) * 
                       (1+datediff(day, @FromDate, @ToDate)),@FromDate)
FROM master..spt_values  v cross join master..spt_values v2
GO

UPDATE DateTable 
 set DateMonth = MONTH(DateColumn)
     ,DateYear = YEAR(DateColumn)
GO

<强>查询

使用两列上的单个索引和两列上的两个单独索引执行以下查询。

SELECT DateMonth,DateYear,COUNT(*)AS RowsCount 来自DateTable GROUP BY DateMonth,DateYear

两个单独的索引

 CREATE INDEX IX_DateMonth ON DateTable(DateMonth)
 GO
 CREATE INDEX IX_DateYear ON DateTable(DateYear)
 GO

具有两个单独索引的执行计划

enter image description here

一个综合指数

CREATE INDEX IX_DateMonth_DateYear7
ON DateTable(DateMonth, DateYear)
GO

enter image description here

具有不同索引的两个表

最后,我创建了两个表,DateTable在两列上都有两个独立的索引,DateTable2在两列上有一个复合索引,并比较了执行计划:

enter image description here

故事的道德

坚持一个复合索引,因为您按两列进行分组,复合索引将导致非群集索引扫描,这将比您在两列上有两个单独索引时获得的表扫描更便宜。