4

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

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

在这方面有什么建议/意见/不建议吗?我们的是 ac#/MSSQL Server R2/Linq 环境。

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

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

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

有用的讨论也与这篇文章中的问题有关,还有 另一个

4

3 回答 3

11

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

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

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

需要注意的事项:

  1. WHERE使用子句进行大量过滤的视图。这些是存储过程或参数化视图的绝佳候选者。
  2. JOIN对于非常大的表来说,那些有时可以成为子查询的好候选者的语句。这确实取决于执行计划。
  3. 似乎执行了多次的语句。这通常是一个很好的迹象,表明应用程序本身并没有很好地管理它往返服务器的频率。我见过会运行相同查询 10 次以上的应用程序。
于 2013-08-28T13:19:46.133 回答
2

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

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

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

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

于 2013-08-28T13:41:36.097 回答
1

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

她建议使用以下步骤转换为非 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 
于 2013-08-30T04:09:10.990 回答