使用 IN vs = 运算符时在非主键列上使用聚集索引
Posted
技术标签:
【中文标题】使用 IN vs = 运算符时在非主键列上使用聚集索引【英文标题】:Using clustered indexes on non-primary key columns when using IN vs = operator 【发布时间】:2012-02-07 05:15:41 【问题描述】:如果我的 Product 表有 CategoryId 列,我知道将 CategoryId 设为聚集索引而不是主键 ProductId 可能是一个好习惯。
如果我对 Product 表的大多数查询看起来像 select * from Product where CategoryId in (1, 2)
而不是更典型的 select * from Product where CategoryId = 1
,这是否仍然适用
【问题讨论】:
【参考方案1】:请非常小心选择您的聚集索引!它非常特别 - 每个表只能有一个,它决定了数据的物理顺序,它用于唯一标识数据页的位置(“行指针”,如果你愿意的话)。
此外,它是您的 SQL Server 数据库中重复次数最多的数据结构(假设您正在谈论的是 SQL Server)。聚簇键也将成为表中每个非聚簇索引的一部分 - 当然在叶级,也可能在索引导航结构中。
在选择集群键时应该格外小心 - 它应该是:
窄(4字节理想)
唯一(毕竟它是“行指针” - 如果您不使其唯一,SQL Server 将 - 为您 - 在后台 - 花费您几个字节对于每个条目 - 乘以您拥有的行数和非聚集索引的数量 - 可能非常昂贵!)
静态(永远不要改变 - 如果可能的话)
理想情况下不断增加,这样您就不会出现可怕的索引碎片(GUID 与良好的集群键完全相反 - 出于这个特殊原因)
它应该是不可为空的,并且理想情况下也可以使用 - varchar(250)
使聚类键非常差
除了这些点之外,其他任何事情都应该是第二和第三级的重要性......
查看 Kimberly Tripp(索引女王)关于该主题的一些博客文章 - 她在博客中所写的任何内容都绝对是无价之宝 - 阅读、消化 - 以此为生! p>
GUIDs as PRIMARY KEYs and/or the clustering key The Clustered Index Debate Continues... Ever-increasing clustering key - the Clustered Index Debate..........again!在您的具体情况下,在Products
表上选择CategoryId
听起来不是一个好主意。一个产品的类别可能会改变,它很可能不是唯一的,因此我认为它不会真正成为一个很好的聚类键。
此外,产品的类别听起来也不是很有选择性 - 所以它甚至可能不会成为一个好的非聚集索引。如果特定查询返回的行数超过总行数的 1-5%,则 SQL 查询优化器无论如何都不会使用大多数索引(因为它们返回的数据太多)。
【讨论】:
这是我第一次阅读这个问题,但我发誓我在某处读过这个完全相同的答案。你只是复制和粘贴你的答案吗?哈哈。 很好的答案和文章,谢谢。对唯一键进行聚类非常不直观 - 我将不得不再阅读几次。 “Products 表上的CategoryId 听起来不是一个好主意......它很可能不是唯一的”——我认为它们的意思是(CategoryId, ProductId)
复合上的聚集索引按这个顺序,这个想法是,当仅通过CategoryId
搜索时,结果将大部分位于相同的物理页面上。
@onedaywhen:(CategoryId, ProductId)
上的那个化合物会是更好的选择,是的!以上是关于使用 IN vs = 运算符时在非主键列上使用聚集索引的主要内容,如果未能解决你的问题,请参考以下文章