如何将guid字段作为主键

本文关键字:字段 guid | 更新日期: 2023-09-27 18:29:15

我现在一团糟,想看看是否能摆脱困境。我有一个数据库,其中包含在uniqueidentifier列上定义的表上的所有主键。这有点强迫我们,把"安全"作为原因之一。另一个我认为比较有价值的原因是一些表参与了复制。

我正在查看数据库,我觉得一个容易避免的未来性能瓶颈是可能在所有表中添加自动递增的bigint列,并使它们成为主键(集群)。并以某种方式适当地"附加"pk-fk关系。但仍保留旧列以备将来使用。

在这方面有什么建议/意见/没有?我们的是一个c#/MSSQL Server R2/Linq环境。

编辑:看着这些评论,我意识到我遗漏了一些重要的细节。所有主键Guid字段都是Clustered的,没有。我没有使用newsequentialId(我们使用Linq到SQL,主键是在客户端生成的。由于涉及复制,我们不确定是否有方法在没有冲突的情况下从不同的客户端环境正确生成顺序ID)。

我的"感觉"是由于已知的事实,即guid列上的聚集索引会导致高度碎片化,并且只会随着数据库的增长而使情况恶化。

此外,我现在并没有真正尝试优化,而是试图纠正一个糟糕的设计,以避免将来数据库过大时出现麻烦。想知道现在做是否值得。

有益的讨论也与本文中的问题有关,以及另一个

如何将guid字段作为主键

数据库的性能调优实际上很简单,但很难。首先,您需要通过在至少一个工作日(最好是两个工作日)内运行一个长时间运行的概要文件来收集针对数据库执行的语句列表。

将该配置文件保存到数据库中,以便对其进行查询,从而可以轻松地找到针对数据库执行的DISTINCT查询。

在确定执行最多的查询后,分析它们的执行计划,很可能与GUID无关,而与查询本身有关(即它们很糟糕),或者您需要不同的索引。

需要注意的事项:

  1. 使用WHERE子句严格筛选的视图。这些都是存储过程或参数化视图的绝佳候选者
  2. JOIN到非常大的表的语句,这些有时可以很好地用于子查询。这取决于执行计划
  3. 出现的语句将被执行多次。这通常是一个好迹象,表明应用程序本身在管理往返服务器的频率方面做得不好。我见过应用程序会运行同一查询10多次

权宜之计可以是使用NEWSEQUENTIALID()而不是NEWID()。至少这样你就不会有那么多碎片。

创建大于以前由生成的任何GUID的GUID自Windows启动以来,在指定的计算机上执行此功能。之后重新启动Windows时,GUID可以从较低的范围重新启动,但是仍然是全球独一无二的。将GUID列用作行时标识符,使用NEWSEQUENTIALID可能比使用NEWID更快作用这是因为NEWID函数会导致随机活动并且使用更少的缓存数据页。使用NEWSEQUENTIALID也有助于完全填充数据和索引页。

http://technet.microsoft.com/en-us/library/ms189786.aspx

请注意,这不一定有助于解决性能问题,具体取决于它们是什么(也许你可以详细说明-INSERTs?SELECT筛选?等等)。

查看Kimberly Tripp的建议http://www.sqlskills.com/blogs/kimberly/disk-space-is-cheap/

她建议以下步骤转换为非GUID集群密钥:

如果你的CL密钥是PK,那么下面是你的步骤:

Take the database offline (sorry, I’m just the messenger!!)
Disable the FKs
Disable the nonclustered indexes
Drop the clustered PK (alter table)
Optionally, add an identity column?
Create the new clustered index
Create the PK as nonclustered
Enable the nonclustered indexes (alter index…rebuild)
Enable the FKs with CHECK (this is very important)
Bring the database online