Sql 避免基于递增键创建聚集索引

Sql 避免基于递增键创建聚集索引,sql,sql-server,performance,indexing,Sql,Sql Server,Performance,Indexing,我从你那里得到这个暗示。然而,我无法理解它的解释 避免基于递增键创建聚集索引 例如,如果表具有代理项 整型主键声明为 身份和聚集指数是一致的 在此列上创建,然后 将时间数据插入此表, 这些行将添加到 桌子。当许多行将被删除时 增加一个“热点”可能发生。“热的” 当许多查询试图 在同一位置读取或写入同一区域中的数据 同时。“热点”会导致 I/O瓶颈。注意。默认情况下,SQL 服务器为服务器创建聚集索引 主键约束。那么在这个 在这种情况下,您应该明确指定 非聚集关键字来指示 将为创建非聚集索引 主键

我从你那里得到这个暗示。然而,我无法理解它的解释

避免基于递增键创建聚集索引 例如,如果表具有代理项 整型主键声明为 身份和聚集指数是一致的 在此列上创建,然后 将时间数据插入此表, 这些行将添加到 桌子。当许多行将被删除时 增加一个“热点”可能发生。“热的” 当许多查询试图 在同一位置读取或写入同一区域中的数据 同时。“热点”会导致 I/O瓶颈。注意。默认情况下,SQL 服务器为服务器创建聚集索引 主键约束。那么在这个 在这种情况下,您应该明确指定 非聚集关键字来指示 将为创建非聚集索引 主键约束

在阅读之前,我认为如果我选择了一个本质上是随机的列,这是不正确的,因为在添加新行时,这将导致不必要的页面重新定位。因此,我认为使用排序列更可取

在阅读了这个提示之后,我认为这是在试图说我们不想使用直接排序的列作为我们的聚集索引,因为对于那些写密集型应用程序来说,将会有一个I/O瓶颈


我真的不明白他们所说的I/O瓶颈的原因。他们是说共享同一页面的操作太多会降低磁盘操作的速度吗?这是怎么发生的?谁能给我解释一下吗?

嗯,我以前听过同样的故事。显然这是个神话。通常建议使用不断增长的集群主键。所有主要的数据库供应商都知道这一点,并缓解了您为避免密钥增长而引用的情况

另见

该报价也与建议相违背(来自同一页):

考虑创建一个代理整数主键(例如标识)。 每个表都必须有一个主键(数据库表中一行的唯一标识符)。代理主键是具有唯一值但对记录本身没有实际意义的字段,因此用户永远不应该看到或更改代理主键。一些开发人员使用代理主键,其他人使用数据字段本身作为主键。如果主键由多个数据字段组成,并且具有较大的大小,请考虑创建代理整数主键。这可以提高查询的性能


他们所指的热点在SQLServer2005及更新版本中不是问题

过去的情况是,所有数据都被写入聚集索引的同一区域和磁盘上的同一扇区,这会导致一次创建大量脏页(脏页是已更改但未提交到磁盘的数据页),当刷新或检查点运行时,这可能会导致问题


由于IO体系结构的变化(据我所知),较新版本不会出现这种行为。

所有现代事务数据库(过去十年中开发的现代方法)都使用事务日志记录

这意味着对数据库的所有更改都以顺序方式写入一个特殊文件(称为事务日志),然后一个特殊的专用进程解析该文件并将更改应用于实际数据。这称为
检查点

如果十个线程将十条记录插入到具有
标识
列的表中,引擎将创建十条事务日志记录(由名为
日志编写器
的单个进程逐个写入),然后,当检查点时,这些记录将写入相应的数据页(也可以通过一个名为
检查点
的进程)

由于它们是连续的,很可能在单个
I/O
操作中将它们写入单个数据页,并且不会发生页面拆分,因为后面没有数据


这样说来,一个不断递增的键上的聚集索引比一个随机键上的聚集索引效率更高。

我明白了,我在热点上做了一些谷歌搜索。你似乎是对的。但是,我仍然不明白为什么写很多脏页会导致性能问题。即使它们不在同一个扇区,我想我们仍然需要这样做将相似数量的数据刷新到磁盘。我将进行更多的谷歌搜索。+1,感谢您的提示。这里有“新
SQL Server 2000
功能”的参考这应该会让你对本文的年代有所了解。@Quassnoi-Yah,我现在从JNK得到了一些提示。我认为这个建议是针对SQL Server 6.5或更早版本的。我在谷歌上搜索并找到了。它说,一旦SQL Server 7.0添加了行级锁定功能,热点问题就解决了。