5

我们一直在经历 SQL 超时,并确定瓶颈是审计表——我们系统中的所有表都包含插入、更新和删除触发器,这些触发器会导致新的审计记录。

这意味着审计表是系统中最大和最繁忙的表。然而,数据只进不出(在这个系统下),所以不需要select性能。

运行select top 10返回最近插入的记录而不是“第一条”记录。 order by当然可以,但我希望 select top 应该根据它们在磁盘上的顺序返回行——我希望这会返回最低的 PK 值。

有人建议我们删除聚集索引,实际上也删除主键(唯一约束)。正如我之前提到的,select在这个系统中不需要从这个表中获取。

聚集索引会对表产生什么样的性能影响?拥有一个无索引、非集群、无键表的(非选择)后果是什么?还有其他建议吗?

编辑

我们的审计涉及 CLR 功能,我现在正在使用和不使用 PK、索引、FK 等进行基准测试,以确定 CLR 功能和约束的相对成本。

经调查,性能不佳与insert报表无关,而是与协调审计的 CLR 功能有关。移除 CLR 并使用直接的 TSQL proc 后,性能提高了 20 倍。

在测试期间,我还确定聚集索引和标识列对插入时间的影响很小或没有影响,至少相对于发生的任何其他处理而言。

// updating 10k rows in a table with trigger

// using CLR function
PK (identity, clustered)- ~78000ms
No PK, no index - ~81000ms

// using straight TSQL
PK (identity, clustered) - 2174ms
No PK, no index - 2102ms
4

4 回答 4

9

根据索引女王 Kimberly Tripp 的说法,在表上拥有聚集索引实际上有助于 INSERT 性能:

聚集索引辩论仍在继续

  • 与堆相比,在聚簇表(但仅在“正确”聚簇表中)中的插入速度更快。这里的主要问题是,在 IAM/PFS 中查找以确定堆中的插入位置比在聚集表中(插入位置已知,由聚集键定义)中的查找要慢。当插入到定义了顺序 (CL) 并且该顺序不断增加的表中时,插入会更快。

资料来源:名为“聚集索引辩论继续”的博客文章....

于 2011-09-01T04:52:49.747 回答
4

Tibor Karaszi 的博客SQLblog.com上提供了一个很好的测试脚本和该场景的描述

我的数字与他的不完全匹配——我看到批处理语句的差异比每行语句的差异更大。

行数约为 100 万时,我相当一致地在聚集索引上执行单行插入循环,其执行速度比在非索引上稍快(聚集大约需要非索引的 97%)。

相反,批量插入(10000 行)更快地插入非索引而不是聚集索引(从 75%-85% 的聚集插入时间)。

clustered - loop        - 1689
heap      - loop        - 1713
clustered - one statement - 85
heap      - one statement - 62

他描述了每个插页上发生的事情:

堆: SQL Server 需要找到行应该去的地方。为此,它使用一个或多个 IAM 页面作为堆,并将这些页面交叉引用到数据库文件的一个或多个 PFS 页面。IMO,这里应该有明显的开销。更重要的是,由于许多用户敲击同一张表,我可以想象阻塞(等待)PFS 和可能还有 IAM 页面。

聚簇表:现在,这很简单。SQL Server 导航聚集索引树并找到该行的位置。由于这是一个不断增加的索引键,因此每一行都将转到表的末尾(链表)。

于 2011-09-01T06:29:40.820 回答
2

没有钥匙的桌子?甚至没有自动递增代理键?:(

只要关键是单调增加插入时的索引维护应该是好的——它只是“在最后添加”。“集群”仅表示表的物理布局遵循索引(因为数据是索引的一部分)。只要索引没有碎片化(参见单调递增位),集群本身/数据就不会在逻辑上碎片化,这不应该是性能问题。(如果有更新,则集群情况略有不同:更新的记录可能“增长”并导致碎片化。)

我的建议是,如果这是选择的路线,那么……用实际的数据/负载对其进行基准测试,然后决定是否有必要提出这样的建议。很高兴看到是否已决定进行此更改,以及为什么。

快乐编码。


此外,任何对订单的依赖ORDER BY都存在设计缺陷。它现在可能可以工作,但它是一个实现细节,并且可能会以微妙的方式发生变化(就像不同的查询计划一样简单)。使用自动增量键,anORDER BY DESC总是会产生正确的结果(请记住,可以跳过自动增量 ID,但除非“重置”,否则它们将始终根据插入顺序增加)。

于 2011-09-01T00:03:32.167 回答
2

我的原始理解是,即使使用聚集索引进行 INSERT 操作通常也比使用堆更快。此外,聚集索引的磁盘空间要求更低。

一些有趣的测试/场景可能会为您的特定情况提供一些启示:http ://technet.microsoft.com/en-us/library/cc917672.aspx 。

于 2011-09-01T01:31:39.110 回答