SQL Server在具有复合字段的聚簇索引上的查询性能

时间:2013-11-10 08:33:45

标签: sql-server performance indexing clustered-index

我有多个链接表CategoryProduct有2列,它们将有数百万条记录:

CREATE TABLE [dbo].[CategoryProduct](
[Category_ID] [int] NOT NULL,
[Product_ID] [int] NOT NULL,
CONSTRAINT [PK_dbo.CategoryProduct] PRIMARY KEY CLUSTERED 
(
    [Category_ID] ASC,
    [Product_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

根据聚集索引,我希望看到物理记录存储在以下结构中:

CategoryID    ProductID
1             2
1             3
2             1
2             3

但是,Select的结果是

CategoryID    ProductID
2             1
1             2
1             3
2             3

为什么数据存储在ProductID组中?这是否反映了数据的实际顺序?如何在CategoryID组中保存数据,以便在匹配的CategoryID被命中时,可以使用连续读取优化下面的查询。

select ProductID from CategoryProduct where CategoryID = value

2 个答案:

答案 0 :(得分:3)

当Sql Server通过执行表扫描或聚簇索引扫描来获取数据时 (如果你的表是聚集的), 由于搜索参数,锁定提示和其他参数,它可能会选择遵循叶页链接,或者它可能会遵循索引分配映射,在大多数情况下,由于发生页面拆分,它们的顺序不同。

使用聚簇索引不能保证速度,Sql server计算不同 检索每个请求的数据的方法,即使是简单的请求(Sql查询优化器是一个非常复杂的系统)。

这也不是以特定顺序获取数据的唯一方式 以特定顺序获取数据是在查询中指定ORDER BY子句 (这是ANSI规范)。

如果您想提高效果,则应该研究请求的查询计划。 有几种方法可以获取请求的查询计划,最简单的方法是在执行请求之前在Sql Magenement Studio工具栏中选择“包含实际查询计划”按钮。

跟进: 使用聚簇索引,数据按照群集定义的顺序进行物理存储,直到群集碎片化为止。 在SELECT中以特定顺序获取数据的 ONLY 方法是向SELECT添加 ORDER BY 子句,而不是创建索引。

答案 1 :(得分:1)

您不应该依赖聚簇键来排序数据。它按群集密钥的顺序存储在磁盘上,但并不意味着返回的数据保证以任何顺序返回。如果您需要订购数据,则需要使用ORDER BY子句。

根据索引的使用情况,您的查询会很好。无论如何,对数据进行排序并不是验证数据的方法。您应该执行查询,检查执行计划并验证确实使用了索引。