如何远离guid字段作为主键

时间:2013-08-28 13:15:49

标签: c# sql-server sql-server-2008

我陷入了一团糟,想看看我是否可以摆脱它。我有一个数据库,其中包含在uniqueidentifier列上定义的表上的所有主键。这有点强加于我们,将“安全”作为其中一个原因。另一个我认为比较有价值的原因是有些表参与复制。

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

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

修改 看看评论,我意识到我遗漏了一些重要的细节。 所有主键Guid字段都是Clustered,而且我没有使用newsequentialId(我们使用Linq to SQL,主键是生成客户端。由于涉及复制,我们不确定如何从不同客户端环境正确生成顺序ID冲突)。

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

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

有用的讨论也与this post中的问题有关 another

3 个答案:

答案 0 :(得分:11)

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

将该配置文件保存到数据库,以便可以查询它,这样您就可以轻松找到针对您的数据库执行的DISTINCT个查询。

在确定执行次数最多的那些之后,分析他们的执行计划,很可能没有与GUID和一切与查询本身有关(即它们非常糟糕)或者您需要不同的索引。

需要注意的事项:

  1. 使用WHERE子句严重过滤的视图。这些是存储过程或参数化视图的绝佳选择。
  2. JOIN到非常大的表,有时的语句可以作为子查询的良好候选者。这取决于执行计划。
  3. 多次执行显示的语句。这通常是一个好兆头,表明应用程序本身并不能很好地管理它往返服务器的频率。我已经看过将运行相同查询10次以上的应用程序。

答案 1 :(得分:2)

权宜之计措施可能是使用NEWSEQUENTIALID()而不是NEWID()。至少这样你就不会得到那么多的碎片。

  

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

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

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

答案 2 :(得分:1)

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