SQL Server 2008索引优化 - 群集查找与非群集包含

时间:2011-09-06 08:33:05

标签: sql-server-2008 query-optimization clustered-index covering-index

这是一个关于指数优化理论的长期涉及的问题。这不是家庭作业,尽管我在微软70-432的样本考试中第一次接触到这个问题。最初的问题是关于一般查询优化,但后来我发现了这个我无法解释的特殊行为。

首先,表格:

CREATE TABLE Invoice_details (
Invoice_id int NOT NULL,
Customer_id int NOT NULL,
Invoice_date datetime DEFAULT GETDATE() NULL,
Amount_total int NULL,
Serial_num int IDENTITY (1,1) NOT NULL)

现在,聚集索引和两个用于测试的索引:

CREATE UNIQUE CLUSTERED INDEX [ix_serial] ON [dbo].[Invoice_details] ([Serial_num] ASC)
/* Below is the "original" index */
CREATE NONCLUSTERED INDEX [ix_invoice_customer] ON [dbo].[Invoice_details] 
    ([Invoice_id] ASC,[Customer_id] ASC)
/* Below is the "optimized" index (adds one included field) */
CREATE NONCLUSTERED INDEX [ix_invoice_customer_inc] ON [dbo].[Invoice_details] 
    ([Invoice_id] ASC,[Customer_id] ASC) INCLUDE ([Invoice_date])

我还在表中添加了一些随机测试数据--100000行。 Invoice_id,Customer_id和Amount_total各自收到自己的随机值(范围1000-9999),Invoice_date收到GETDATE()加上随机秒数(范围1000-9999)。我可以提供我使用的实际例程,但不认为具体情况是相关的。

最后,查询:

SELECT Invoice_id,Customer_id,Invoice_date FROM Invoice_details WHERE Customer_id=1234;

显然,查询的第一步是非聚集索引扫描。无论使用哪个索引,第一步都将返回相同数量的索引行。使用“原始”索引,下一步将是通过聚簇索引进行查找以检索Invoice_date,然后在两个集合之间进行内部JOIN。使用“优化”索引,该字段包含在索引叶中,因此规划人员直接返回结果。

哪个索引导致执行速度更快,为什么?

2 个答案:

答案 0 :(得分:1)

取决于...... tipping point

答案 1 :(得分:0)

假设没有碎片等问题,那么它就归结为查询的选择性。

2个指数非常相似。因为"优化"一个包含叶页中的附加列,然后对该索引的完整扫描可能意味着与原始页相比需要读取更多页。但是,如果要返回的行数不止一些,我会发现不需要查找的好处很快就会超过这个小缺点。