如何强制查询不使用给定表上的索引?

问题描述 投票:42回答:3

我目前正在做一些测试,以确定在SQL Server 2005中给定列上包含索引对性能的影响。

我正在使用的测试数据集大约有7200万行(大约6 GB的数据)。为了实际上test索引的性能,我需要能够比较有和没有索引的性能。

很好,但是首先创建索引并不是一个便宜的操作。如果我要测试没有索引的表,则至少需要禁用索引。要测试索引,我需要重新启用它,这需要花费很长时间。

有什么方法可以强制SQL Server 2005在执行查询时忽略给定的索引?我不想只为了测试查询就禁用索引,因为禁用索引需要很长时间。

sql sql-server-2005 indexing
3个回答
62
投票
SELECT * FROM MyTable WITH (INDEX(0)) WHERE MyIndexedColumn = 0
查询通常会使用MyIndexedColumn上的索引,但是由于有表提示,它将改为进行tablescan。


SELECT * FROM MyTable WITH (INDEX(IndexName)) WHERE MyIndexedColumn = 0
查询通常会使用MyIndexedColumn上的索引,但是由于有表提示,它将改为使用名为IndexName的索引。

8
投票
我正在使用所有不同类型的数据库,并且在需要时永远无法记住特定提示。因此,我使用的是一种纯SQL方法(当前),该方法可用于所有与我无关的数据库。

想法是通过混淆SQL中的各个表达式,使数据库无法使用特定索引。例如。当where子句使数据库认为使用索引最好解决该问题时,则不是。

SELECT * FROM MyTable WHERE MyIndexedColumn + 0 = 0

类似地,您可以在字符串值中添加一个空字符串。当前的优化器无法解析此类表达式,无法使用(MyIndexedColumn)上的索引。

这实际上是我在书中描述的反模式。以下是有关math in SQL

的页面

对于临时测试绝对足够好。在生产代码中,提示当然更具表达力!


-4
投票
您可以在运行测试代码的同一事务中禁用不想使用的索引,只需确保在最后回滚该事务即可。这样可以确保测试代码不会使用索引,但可以防止索引被实际禁用。

BEGIN TRANSACTION ALTER INDEX [MyIndex] ON MyTable DISABLE; EXEC TestCode; ROLLBACK

如果您遇到一个复杂的案例,即您的测试代码在不同的时间使用多个索引,并且您想测试添加一个新的索引是否可以改善情况,那么这样做会更好。
© www.soinside.com 2019 - 2024. All rights reserved.