【问题标题】:SQL Server Indexes - Initial slow performance after creationSQL Server 索引 - 创建后初始性能缓慢
【发布时间】:2010-01-14 23:05:17
【问题描述】:

使用 SQL Server 2005。这是我在进行一些性能分析时注意到的。

我有一个大约 1 亿行的大表。我正在比较表上不同索引的性能,以查看最适合我的测试方案的最佳方案,即在该表上执行大约 10,000 次插入,以及其他表上的其他操作。在我的测试运行时,我正在捕获一个 SQL Profiler 跟踪,当测试完成后我将其加载到一个 SQL 表中,以便我可以分析统计信息。

在表上重新创建一组不同的索引后的第一次测试运行速度明显比后续运行慢 - 通常在创建索引后第一次运行时在此表上的插入速度慢约 10-15 倍。

每次测试前我都会清除数据和执行计划缓存。

我想知道的是,新创建的一组索引最初性能较差的原因是什么? 有没有办法让我在第一次运行时监控导致此问题的原因?

【问题讨论】:

    标签: sql-server-2005 performance indexing


    【解决方案1】:

    一种可能性是默认的fill factor 为零正在发挥作用。

    这意味着索引中“没有空间”来容纳您的插入。插入时,需要在索引中进行分页,增加了一些空白空间来存储新的索引信息。当您执行更多插入时,索引中会创建更多空间。一段时间后,拆分率会下降,因为您的插入内容会命中未完全填充的页面,因此不需要拆分。需要分页的插入比不需要分页的插入更昂贵。

    您可以在创建索引时设置填充因子。它是在使用的空间和不同操作的性能之间进行的经典权衡。

    我要加入一些Sybase ASE docs 的链接,因为它们写得很好,而且大部分也适用于 SQL Server。

    【讨论】:

    • 出于某种奇怪的原因,我什至没有考虑填充因子:/ 这绝对是我要测试的东西 - 我认为你可能是对的。理想情况下,我希望看到这些页面拆分发生,这样我就可以实际 - 知道如何监控它们吗?
    • 内置 perfmon,它会检测服务器(因此会减慢速度),但会捕获包括页面拆分/秒在内的大量数据。
    • 干杯 - 会让人眼前一亮 - 我喜欢“看到”发生的事情直接将它们与性能峰值联系起来!
    • 现场欢呼,我已经能够监控页面拆分并真正看到它们的效果。
    【解决方案2】:

    澄清一下:

    1) 您在具有 100m 预先存在的行的表上构建索引。

    2) 你在表中插入 10k 行

    3) 你在表中插入另外 10k 行

    第 3 步比第 2 步快 10 倍?

    新索引是什么类型的索引 - 不是聚集的,对吗?因为在聚集索引上插入会导致非常不同的行为。此外,2 个插入的配置文件是否有任何显着差异,因为根据聚集索引,它们将具有不同的行为。通常,它应该没有聚集索引,或者聚集在一个递增的键上。

    【讨论】:

    • 是的,在这 3 个步骤上是正确的。我正在尝试不同的聚集索引。我使用 FieldA 上的聚集索引运行了一些测试。然后我删除它,并在 FieldB 上创建一个聚集索引,以查看它的执行情况。我知道他们会有不同的行为——这比更改索引后的第一次测试运行要慢得多,它明显慢于使用相同索引运行的后续测试。
    • 嗯,聚集索引并不是真正的索引。这只是行的数据页的顺序。当你有一个聚集索引时,你真的希望它不会导致很多页面拆分,所以通常最简单的方法是确保聚集与插入顺序匹配 - 或者只是有一个只有非聚集索引的堆表(也许包含列以更好地满足您的阅读需求)。请记住,所有索引实际上只会减慢 INSERT。
    • 是的,我做这个测试的部分原因是为了确保我们只有真正需要的索引,以便在插入/更新速度和读取速度之间取得适当的平衡。关于考虑只有非聚集索引的堆表的好建议——这对我很有好处——也会尝试一下。
    猜你喜欢
    • 2014-06-26
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多