【问题标题】:SQL Server 2008 Index Optimization - clustered lookup vs nonclustered includeSQL Server 2008 索引优化 - 集群查找与非集群包含
【发布时间】:2011-11-11 03:14:31
【问题描述】:

这是一个关于索引优化理论的冗长而复杂的问题。这不是家庭作业,尽管我是在 Microsoft 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。使用“优化”索引,该字段包含在索引叶中,因此规划器直接返回结果。

哪个索引可以加快执行速度,为什么?

【问题讨论】:

  • 顺便说一句:你会告诉我们你得到的令人惊讶的结果吗?
  • 我没想到包含的索引会表现得更差。在最初的测试问题中,我的答案是在 Customer_id 上创建一个新的非聚集索引。那是错误的......测试说包含的字段更多的是优化。在我的测试中,结果表明我的方法不仅速度更快,而且与默认使用的聚集索引扫描相比,包含的字段实际上降低了性能。

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


【解决方案1】:

这取决于...tipping point

【讨论】:

    【解决方案2】:

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

    这两个索引非常相似。因为“优化”的页面在叶子页面中包含一个额外的列,所以对该索引的完整扫描很可能意味着与原始页面相比需要读取更多页面。但是,如果要返回的行多于几行,我预计不需要查找的好处很快就会超过这个小缺点。

    【讨论】:

    • @@sahlean - 我只是想支持你的答案,因为你打败了我,让我加入了the "tipping point" 链接,但你已经删除了它!
    • 我觉得答案(我的答案)太简单了。
    • @@sahlean - 不,我认为该链接确实说明了一切。我打算自己链接到它,但很生气你打败了我!
    • 您的答案(你们俩)都已确定,如进一步的实验所示。额外的包含字段增加了索引的大小,因此由于页面读取的增加而使扫描变慢。在某个点(即表大小)之后,速度优势进入集群查找。指向 sahlean 的“第一”。 :) 非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 2011-11-28
    • 2011-01-23
    • 2015-03-14
    • 2015-06-13
    相关资源
    最近更新 更多