Sql server 如何使用LIKE语句强制执行查询的合理执行计划?

Sql server 如何使用LIKE语句强制执行查询的合理执行计划?,sql-server,Sql Server,在创建临时查询以查找表中的信息时,我反复遇到过这个问题 假设我有一个包含一百万条记录的表,其中包含id-int、createddatetime-timestamp、category-varchar(50)和content-varchar(max)字段。我想查找在内容字段中具有特定字符串的最后一天的所有记录。如果我创建这样的查询 select * from table where createddatetime > '2018-1-31' and content like '%som

在创建临时查询以查找表中的信息时,我反复遇到过这个问题

假设我有一个包含一百万条记录的表,其中包含id-int、createddatetime-timestamp、category-varchar(50)和content-varchar(max)字段。我想查找在内容字段中具有特定字符串的最后一天的所有记录。如果我创建这样的查询

select *
from table
where createddatetime > '2018-1-31'
    and content like '%something%'
它可能在一秒钟内完成,因为在最后一天可能只有100条记录,所以LIKE子句只对少量记录起作用

但是,如果我在where子句中再添加一项

select *
from table
where createddatetime > '2018-1-31'
    and content like '%something%'
    and category = 'testing'
然后,在锁定桌子的同时,可能需要很多分钟才能完成

它似乎正在从在有限的记录集上首先执行所有直接的WHERE子句项,然后执行类似的操作,转变为首先执行LIKE子句。有时甚至会出现多个LIKE语句,再添加一个语句会导致查询从一秒钟变为几分钟

我发现的唯一解决方案是生成一个中间表(可能临时表可以工作),根据基本WHERE子句项插入记录,然后运行一个单独的查询以通过一个或多个LIKE语句进行筛选。我尝试过各种JOIN和CTE方法,但通常没有任何改进。或者,如果尝试转换多个LIKE语句的逻辑,CHARINDEX似乎也可以工作,但很难使用

在查询语句中是否有任何提示或内容可以告诉sql server在按类似项进行过滤之前,先等待记录被基本WHERE子句项过滤


事实上,我只是尝试了这种方法,它有同样的问题

select *
from (
    select *, charindex('something', content) as found
    from bounce
    where createddatetime > '2018-1-31'
) t
where found > 0

虽然子查询在几秒钟内独立返回,但整个查询永远不会返回。为什么这样不好呢?

不奇怪,但是我在使用临时表时比嵌套的select语句更幸运。。。它将隔离第一个数据集,然后您可以从中进行选择。如果你正在寻找快速和肮脏,这通常是服务于我的目的为特设,这可能会有所帮助。如果这是一个永久存储过程,那么从长远来看,索引建议可能会更好地为您服务

select *
into #like
from table
where createddatetime > '2018-1-31'
    and content like '%something%'

select * 
from #like 
where category = 'testing'

这并不奇怪,但我在临时表方面比嵌套的select语句更幸运。。。它将隔离第一个数据集,然后您可以从中进行选择。如果你正在寻找快速和肮脏,这通常是服务于我的目的为特设,这可能会有所帮助。如果这是一个永久存储过程,那么从长远来看,索引建议可能会更好地为您服务

select *
into #like
from table
where createddatetime > '2018-1-31'
    and content like '%something%'

select * 
from #like 
where category = 'testing'

因为您的LIKE语句由于前导通配符而不可争论。您已经删除了利用索引查找具有该索引的行的功能。where谓词不按顺序过滤,因为您将LIKE放在查询的末尾,这并不意味着引擎将以这种方式处理它们。您不能在一个查询中短路where谓词,这似乎是您要问的问题。@SeanLange感谢您使用这个术语,因为我以前从未见过它。当SearchedId尝试更新统计信息时,会生成大量要阅读的资料?获取更多信息有助于回答根本问题。不要因为看不到链接就把问题一笔勾销。因为你的LIKE语句由于前导通配符是不可争论的。您已经删除了利用索引查找具有该索引的行的功能。where谓词不按顺序过滤,因为您将LIKE放在查询的末尾,这并不意味着引擎将以这种方式处理它们。您不能在一个查询中短路where谓词,这似乎是您要问的问题。@SeanLange感谢您使用这个术语,因为我以前从未见过它。当SearchedId尝试更新统计信息时,会生成大量要阅读的资料?获取更多信息有助于回答根本问题。不要因为看不到链接就把问题一笔勾销掉。这是我发现的唯一一个能持续工作的东西!祝你好运!这是我发现的唯一一件持续有效的东西!祝你好运!