我有一个表,它的复合聚集指数(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%),但是在索引重建和stats更新之后,我确实被期望打破我的查询。
估计的执行计划是:
SELECT Cost: 0%Clustered Index Seek (Clustered)[MyTable].[IX_MyCompoundIndex] Cost: 100%这是因为索引是聚集索引吗?我是不是遗漏了什么?
发布于 2012-09-24 14:48:17
您应该避免SELECT * --即使您确实需要表中的所有列(这是很少见的)。
而且,你在这里做了一些非常危险的事情。你知不知道你的终点站已经结束了,所以你可能会在午夜的时候把2013-01-01年间的数据包括进去?尝试:
AND myDateTimeColumn >= '20120101'
AND myDateTimeColumn < '20130101'(这不会改变性能,但是它更容易生成,并且无论底层数据类型是什么,都保证它是准确的。)
为了消除对查询时间的分析中的网络延迟,您可以考虑SQL Sentry计划资源管理器 --它允许您通过对服务器运行查询来生成实际计划,但放弃结果,所以这不是一个干扰因素。
免责声明:我为Sentry工作。
发布于 2012-09-24 15:07:59
查询的执行时间将花费在读取索引的btree的足够页面上,以生成结果。将索引碎片整理将相邻的行放在一起,从而减少需要读取的页面数。它也可以受益于将很大程度上随机的io模式转换为顺序模式。
如果您的行很宽,并且每个页面没有多少行,那么您将不会看到行数的大幅度减少。
如果索引填充因子较低,那么每页的行数就不会那么多。
如果您的页面在缓存中,您将不会看到任何流和随机IO的好处。
如果您在机器上有空闲的CPU容量,那么使用页面压缩可能会使您受益。这实际上是用更多的CPU来换取更少的IO。
https://stackoverflow.com/questions/12567235
复制相似问题