sql—当使用newsequentialid()作为主键时,我的聚集索引应该是什么?

vuv7lop3  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(290)

我正在使用newsequentialid为表中的主键生成guid。
根据文件(https://docs.microsoft.com/en-us/sql/t-sql/functions/newsequentialid-transact-sql?view=sql-server-ver15),顺序guid不保证按顺序生成。
重新启动windows后,guid可以从较低的范围重新启动,但仍然是全局唯一的
基本上,在你重启机器之前,它们是正常的。
对于autoincrement主键,将其作为聚集索引是有意义的,因为可以保证插入的行位于末尾。
对于guid主键,将其作为聚集索引是没有意义的,因为它是随机的,不太可能在末尾插入一行。
顺序guid主键呢?主键应该是聚集索引还是应该尝试查找另一列(如datecreated字段)?问题是像datecreated这样的字段不会是唯一的字段。如果我没有任何字段是唯一字段,我应该做什么作为聚集索引?

j9per5c4

j9per5c41#

对于聚集索引,顺序guid比非顺序guid安全得多。一般来说,数据库不会特别频繁地重新启动。重新启动确实会导致页面分裂和碎片化,但这通常不是太大的考虑因素,因为重新启动很少。
也就是说,主键不需要是聚集索引键。你可以有一个 identity 列或创建日期/时间作为聚集索引,基本上消除了这个问题。

11dmarpk

11dmarpk2#

不久前我写了一篇关于这个的长文章。tl/dr的特点是使用顺序guid作为聚集索引键是很好的。guid实际上是插入到索引的中间,但是如果中间索引插入点的数目很少(这里只有一个),则不会导致昂贵的页拆分或导致有害的碎片。
良好的页面分割和顺序guid密钥生成
同样的行为也适用于使用复合键作为聚集索引,其中前导键列的基数较低。例如(customerid,transactionid)。每个customerid将有一个半满的页面,其中有空间用于下一个transactionid,当该页面填满时,将分配一个新的页面。

相关问题