每隔一段时间,就需要检查一下。这是这样一个时代。
我有用于报告的表格。它们每天或每天多次删除/插入,以始终使用连续的日期范围(如本月至今或滚动的 45 天)从源“刷新数据”。源数据对它们没有 ID 或唯一性。
到目前为止,惯例是在日期上使用聚集索引——每个表都有一个日期,每个查询都使用一个日期(99% 的时间)。如果表有使其唯一的列,我已将它们添加到集群中以使其唯一(例如,状态和电子邮件)。如果没有,我添加了一个 ID IDENTITY 以使其唯一。
研究似乎建议“使用递增的 ID”,几乎没有偏差。但是,使用此约定的性能非常好 - 除非我在某处遗漏了什么。
所以虽然这很好,但有时同行检查可能是一件好事:)
- 日期作为聚集索引中的前导列有任何问题(考虑到上述情况)?
- 添加 MY OWN ID Identity 列的唯一性是否比 MS SQL 为我做的更好?
- 先加ID,再加日期会更好吗?
环境:Azure SQL
没有我能想到的。在非随机/顺序类型的列上聚类通常很好。日期通常很符合这个标准,而不是
UNIQUEIDENTIFIERS
到处都是 GUID ( )。聚集索引是实际表的逻辑排序(进入 B-Tree 数据结构)。通过使用非随机或顺序数据类型作为索引键,这可以在为所有相关行寻找 B 树的该子集时实现最大效率。我知道没有理由这样做,但我会假设你这样做不会造成太大伤害,因为你正在使用一个
IDENTITY
我也假设很少更改的列。唯一的缺点是你让你的聚集索引有点胖。如果您计划使用任何非聚集索引,它们也会因此变得稍微重一些,因为所有非聚集索引也存储聚集索引键。如果您计划使用经常更新的列作为聚集索引键的一部分,那么这对性能来说并不是那么好,因为每次键值更改时,它都必须更新所有非聚集索引中的所有相关行同样,阻塞会导致大量额外开销。不,可能不是。如果您的查询没有使用
ID
谓词(JOIN
,WHERE
,HAVING
子句)中的字段,那么在索引中以它开头会使该索引不再适用于这些查询。同样,这是因为数据是按照索引中定义的字段的顺序进行逻辑排序的。如果 B-Tree 首先按 排序ID
,但您的查询没有按 过滤ID
,那么 SQL 引擎将没有有效的方法来直接遍历 B-Tree 到您的查询过滤的行子集。