【问题标题】:No real performance gain after index rebuild on SQL Server 2008在 SQL Server 2008 上重建索引后没有真正的性能提升
【发布时间】:2012-09-24 14:37:19
【问题描述】:

我有一个表,其复合聚集索引 (int, DateTime) 有 99% 是碎片化的。

碎片整理并确保更新了统计信息后,我在运行此查询时仍然得到相同的响应时间:

SELECT *
FROM myTable
WHERE myIntField = 1000 
AND myDateTimeField >= '2012-01-01' 
and myDateTimeField <= '2012-12-31 23:59:59.999'

嗯,我看到响应时间略有改善(例如 5-10%),但我真的希望在索引重建和统计信息更新后突然查询。

预计的执行计划是:

  1. SELECT Cost: 0%
  2. Clustered Index Seek (Clustered)[MyTable].[IX_MyCompoundIndex] Cost: 100%

这是因为索引是聚集索引吗?我错过了什么吗?

【问题讨论】:

  • 表中有多少行,有多少行匹配这个查询?桌子有多宽?多久时间?你在哪里测量这个(Management Studio,你的应用)以及你在离数据源多远的地方检索结果?
  • 你看过统计数据了吗?该集合可能完全在记忆中,有助于解释您在此处看到的内容。
  • 到底是什么问题?返回多少行?查询需要多长时间?

标签: sql-server-2008 indexing clustered-index


【解决方案1】:

您应该避免使用SELECT * - 即使您确实需要表中的所有列(这种情况很少见)。

另外,你在这里做的事情非常危险。您是否知道您的结束范围会向上取整,因此您可能会在午夜包含 2013 年 1 月 1 日的数据?试试:

AND myDateTimeColumn >= '20120101' 
AND myDateTimeColumn <  '20130101'

(这不会改变性能,但生成更容易并且无论底层数据类型是什么都保证准确。)

要从您的查询时间分析中消除网络延迟,您可以考虑SQL Sentry Plan Explorer - 它允许您通过对服务器运行查询来生成实际计划,但会丢弃结果,因此这不是干扰因素.

免责声明:我为 SQL Sentry 工作。

【讨论】:

  • 当您使用它时 - 将日期字符串文字更改为“安全的”ISO-8601 格式 - YYYYMMDD 没有任何破折号或斜线或任何东西!
  • @Aaron Bertrand 我放的代码只是一个示例,请不要介意 select 的编写方式,它不会影响我正在寻找的性能。
【解决方案2】:

查询的执行时间将花费在读取索引 btree 的足够页面以生成结果。对索引进行碎片整理会将相邻的行放在一起,从而减少需要读取的页数。它还可以受益于将很大程度上随机的 io 模式转换为顺序模式。

如果您的行很宽,并且每页没有很多行,那么行数不会减少很多。

如果您的索引填充因子较低,则每页不会有那么多行。

如果您的页面在缓存中,您将看不到任何流式传输和随机 IO 优势。

如果您的机器上有空闲的 CPU 容量,您可能会从使用页面压缩中受益。这实质上是用更多的 CPU 换取更少的 IO。

【讨论】:

    猜你喜欢
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多