【问题标题】:T-SQL LIKE using variable and index使用变量和索引的 T-SQL LIKE
【发布时间】:2015-03-15 12:31:35
【问题描述】:

如果[column1]被索引,下一个查询可能使用索引:

SELECT * FROM [table] WHERE [column1] LIKE 'starts%'

如果我引入一个变量,下面的查询将永远不会使用索引:

DECLARE @starts nvarchar(100)
SET @starts = 'starts%'
SELECT * FROM [table] WHERE [column1] LIKE @starts

我想根据用户输入实现 StartsWith 搜索,但我不确定选择哪种方式:

  1. 为 LIKE 正确转义用户输入,以便优化器能够根据文字选择计划

  2. 使用 WITH(FORCESEEK)

  3. 使用选项(重新编译)

【问题讨论】:

  • 另一种选择是查看全文搜索。
  • 为什么你的第二个查询不使用索引?
  • 我暂时不打算维护全文搜索索引
  • 由于变量,第二个查询以某种通用方式编译。我在互联网的某个地方读到了这些东西
  • 虽然更多地关注参数化而不是局部变量,但这篇 dba 帖子可能至少有点用处:dba.stackexchange.com/questions/33698/…

标签: sql sql-server sql-server-2008 tsql sql-like


【解决方案1】:

还有一个您没有列出的选择。您可以使用OPTIMIZE FOR 选项强制查询优化器对预期变量值的性质做出正确假设。这似乎非常符合您的需求。

DECLARE @starts nvarchar(100)
SET @starts = 'starts%'
SELECT * FROM [table] WHERE [column1] LIKE @starts
OPTION (OPTIMIZE FOR (@starts = 'mnopq%'))

this blog 中有更详细的描述。还有MSDN documentation

指示查询优化器将特定值用于本地 编译和优化查询时的变量。该值被使用 仅在查询优化期间,而不是在查询执行期间。

【讨论】:

  • 无论如何我都必须在 OPTIMIZE FOR 语句中正确转义用户输入,对吧?
  • 我刚刚在 AdventureWorks2008 上进行了测试,但它不起作用 :( .QUERYEXECUTION PLANS
  • 我测试过,它可以工作,但是在第一个选择之前我没有看到任何优势
  • @svolkov - 我不明白你关于转义用户输入的问题。你能举个例子吗?
  • @svolkov - 文字只是用来指导查询优化器。当您编写存储过程时,您只会想出一次文字。文字是什么并不重要,除了你在其中放置“%”的位置,这是重点。您可以使用与我相同的文字“mnopq%”。你是说传入的参数一次可能是'hello%',下一次可能是'%world'?我不是这样读你的问题的,因为你说你正在写一个“开头”。
猜你喜欢
  • 2014-08-22
  • 2019-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
  • 2011-11-02
  • 1970-01-01
  • 2015-07-28
相关资源
最近更新 更多