具有意外索引扫描的慢查询

zer*_*kms 4 sql indexing performance

我有这个问题:

SELECT *
FROM sample
   INNER JOIN test ON sample.sample_number = test.sample_number
   INNER JOIN result ON test.test_number = result.test_number
   WHERE sampled_date BETWEEN '2010-03-17 09:00' AND '2010-03-17 12:00'
Run Code Online (Sandbox Code Playgroud)

这里最大的表是RESULT,包含11.1M记录.左边2个表约1M.

此查询运行缓慢(超过10分钟)并返回大约800条记录.执行计划显示所有11M记录上的聚集索引扫描(通过它的PRIMARY KEY(result.result_number,它实际上不参与查询)).RESULT.TEST_NUMBER是一个群集主键.

如果我改变2010-03-17 09:00到2010-03-17 10:00 - 我得到大约40条记录.它执行300毫秒.和计划显示索引搜索(over result.test_number索引)

如果我将SELECT子句中的*替换为result.test_number(用索引覆盖) - 那么在第一种情况下所有都变快了.这指向hdd IO问题,但没有说明改变计划.

那么,有什么想法吗?

更新: sampled_date在表样本中并由索引覆盖.此查询中的其他字段:test.sample_number也由index和result.test_number覆盖.

更新2: 显然比sql server在任何原因都不想使用索引.

我做了一个小实验:我用结果删除INNER JOIN,选择所有test.test_number然后再做

SELECT * FROM RESULT WHERE TEST_NUMBER IN (...)
Run Code Online (Sandbox Code Playgroud)

当然,这很快.但我无法得到有什么不同,以及为什么查询优化器选择这种不恰当的方式来选择第一种情况下的数据.

更新3: 备份数据库并使用新名称恢复到数据库后 - 即使在更多范围内,这两个请求也能按预期快速运行...

那么 - 是否有任何特殊的命令来清理或优化,可能与此相关?:-(

Gab*_*abe 7

有几件事要尝试:

  • 更新统计信息
  • 在查询中添加有关使用哪个索引的提示(在SQL Server中,您可以WITH (INDEX(myindex))在指定表后指出)

编辑:您注意到复制数据库使它工作,这告诉我索引统计信息已过期.您可以UPDATE STATISTICS mytable定期更新它们.

使用EXEC sp_updatestats更新整个数据库.