0

我有一个表,其复合聚集索引 ( 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%

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

4

2 回答 2

1

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

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

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

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

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

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

于 2012-09-24T14:48:17.537 回答
0

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

如果您的行很宽并且每页没有很多行,您将不会看到行数减少太多。

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

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

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

于 2012-09-24T15:07:59.697 回答