SQL Server是否像(“%%”)查询一样进行优化?

SQL Server是否像(“%%”)查询一样进行优化?,sql,sql-server,search,stored-procedures,sql-like,Sql,Sql Server,Search,Stored Procedures,Sql Like,我有一个对记录执行搜索的存储过程 问题是一些来自UI的搜索条件可能是空字符串。 因此,当未指定条件时,LIKE语句变得多余 如何有效地执行该搜索或Sql Server?或者,它是否像“%”查询一样进行优化,因为它意味着没有可比较的内容 存储的过程如下所示: ALTER PROC [FRA].[MCC_SEARCH] @MCC_Code varchar(4), @MCC_Desc nvarchar(50), @Detail nvarchar(50) AS BEGIN

我有一个对记录执行搜索的存储过程

问题是一些来自UI的搜索条件可能是空字符串。 因此,当未指定条件时,LIKE语句变得多余

如何有效地执行该搜索或Sql Server?或者,它是否像“%”查询一样进行优化,因为它意味着没有可比较的内容

存储的过程如下所示:

ALTER PROC [FRA].[MCC_SEARCH]
@MCC_Code varchar(4),
@MCC_Desc nvarchar(50),
@Detail nvarchar(50)
AS
BEGIN             
       SELECT
             MCC_Code,
             MCC_Desc,
             CreateDate,
             CreatingUser

       FROM
              FRA.MCC (NOLOCK)
       WHERE
             MCC_Code LIKE ('%' + @MCC_Code + '%')
             AND MCC_Desc LIKE ('%' + @MCC_Desc + '%')
             AND Detail LIKE ('%' + @Detail + '%')
       ORDER BY MCC_Code

END

如果使用LIKE子句,并指定通配符%作为searchstring的前缀,SQL Server和所有其他DBMS将无法使用该列上可能存在的索引

如果使用空的搜索参数,我不知道它是否优化了查询。。。如果你看一下执行计划,也许你的问题会得到回答

编辑:我刚刚签出了这个,这个语句的执行计划是:

select * from mytable
select * from mytable where description like '%'
与此语句的执行计划完全相同:

select * from mytable
select * from mytable where description like '%'

这两个SQL语句都只是使用聚集索引扫描。

关于使用索引的最佳执行计划-否。前缀通配符阻止使用索引,从而导致扫描

如果搜索词的末尾也没有通配符,那么这种情况可以得到优化——这是我不久前在博客上写的:

更新 为了澄清我的观点: 比如“某物%”—能够使用索引 像“%Something”-不能使用开箱即用的索引。但是你可以按照我链接到的反向技术来优化它,允许它使用索引。 像“%Something%”-无法使用索引。你不能做任何事情来优化你的喜好。

简单的答案是-不 答案很长——绝对不是

它是否像“%”查询一样进行优化,因为它意味着没有可比较的内容

这句话是不真实的,因为有些东西可以比较。以下是等效的

WHERE column LIKE '%%'
WHERE column IS NOT NULL
IS NOT NULL需要表扫描,除非列中只有很少的非NULL值并且索引良好

编辑 有关SQL Server中动态搜索过程的资源: 您只需阅读Erland Sommarskog的这篇文章,SQL Server MVP选择您的版本,或者两者都阅读即可


否则,如果在包含样式搜索中需要很好的性能,请考虑使用SQLServer FultEXCELL引擎.< /P> THERE用于这种情况,但是使用类似的子句可以防止优化器使用其他索引。如果执行select和select where…%,您将得到不同的执行计划。显然,由于select from将始终导致索引扫描,因为索引已完全覆盖。您或我没有抓住要点。阅读您的答案,OP可能会得出这样的结论:没有性能惩罚,但实际上可能存在。假设您的查询只需要返回一个索引列。在另一列上添加where%%子句将导致性能开销。您所说的确实正确。但是,在提问者提出的实际案例中,我认为这是很明显的,因为他选择了where子句中的列,我认为无论他是否使用where%%子句,都将始终使用相同的索引。事实上,我们不知道topicstarter是否在detail列上有索引,例如,因为这确实可能是一个会影响exec的列plan@Richard-不,我是说最后。i、 e.像“%Something”-因为在该条件的末尾没有通配符,所以可以根据我的博客对其进行优化-基本上,将列值反转为计算列,然后反转搜索词,搜索词的结尾是%,因此可以使用索引。@Richard-你说的是另一种情况-我特别指的是当你想查找以给定字符串结尾的项目,如“%Something”,除非你遵循我在博客中提到的方法,否则不会使用索引。你说的是查找以给定字符串开头的项,比如“Something%”,当然可以在索引上使用,而不必进行任何反向搜索。@Richard-是的,我知道-我在解决OP要求的特定问题后将其作为第二点添加,因为我觉得它可能会为现在和将来阅读此问题的人增加价值。简而言之,我们只是想强调,%某物可以优化,因为不是每个人都知道,%某物可以优化,%……而%某物%不能用LIKE优化。与链接到完整的参考,并没有太多的细节这里,特别是因为它不是直接回答特定的Q。这是不正确的,就像可以优化,即使当搜索在中间的领域。