我有这样的查询:
select top(10) * from dbo.myTable where DisplayName like 'farm%'
这导致在 DisplayName 上进行索引查找,因为通配符在尾部。但是,当我这样做时情况并非如此:
declare @val varchar(200) = 'farm'
select top(10) * from dbo.myTable where DisplayName like @val + '%'
或者这个:
declare @val varchar(200) = 'farm%'
select top(10) * from dbo.myTable where DisplayName like @val
在这些情况下,SQL 回退到慢得多的索引扫描操作。所定位的值是一个在运行时提供的参数,因此显然我不能仅将第一个查询用于我的目的。
有什么办法可以:
- 确保 SQL 索引查找值,并且
- 将此逻辑存储在预编译的存储过程中。查询需要很快,所以我不想不得不求助于每次执行都强制重新编译的方法(即使编译开销 + 索引查找仍然比索引扫描快)
我知道通配符的存在与否会影响执行计划,但 SQL 似乎不理解通配符总是被使用,即使您将它连接到值,如查询 #2 中一样。
最佳答案
SQL Server can use a range seek for these queries (在变量包含前导通配符的情况下,范围最终就是整个索引)。
如果在这种情况下没有选择这样做,可能是因为变量的使用意味着它没有准确估计选择性。您可以尝试添加 OPTION (RECOMPILE)
提示,以便它考虑实际变量值。
关于sql-server - SQL 没有优化我的参数化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12338903/