首页 > 解决方案 > 如何为 OR 操作创建非聚集索引

问题描述

要求:表Product有名称和条形码

我想创建一个非聚集索引以使用名称或条形码进行搜索

查询样本

DECLARE @Filter NVARCHAR(100) = NULL

SET @Filter = '%' + ISNULL(@Filter, '') + '%'

SELECT *
FROM Product
WHERE Name LIKE @Filter
OR Barcode LIKE @Filter

请帮助我提供独立于名称和条形码的两个索引或使用一个索引包括名称和条形码的任何解决方案

标签: sql-serverwhere-clausenon-clustered-indexor-operator

解决方案


你手头有几个问题。首先,即使存在索引,Name或者Barcode您的过滤器表达式也无法从索引中受益(在传统意义上添加索引),因为该表达式是不可分割的。Brent Ozar 有一篇很棒的文章解释了为什么 %string% 很慢

其次,您不能创建单个索引来覆盖两个单独列上的过滤器,其中每列上的过滤器都是独立的。这意味着您要么使用两个单独的过滤器(例如:您的 OP),要么您的查询仅包含一个过滤器,Name = 'NameValue'反之亦然。具有 where 子句的查询:

WHERE 
    Name = 'NameValue' 
    OR 
    Barcode = 'BarcodeValue'

Name如果单独的索引存在于第一个列出的列并且是第一个列出的列,则只能为两个过滤器表达式查找索引Barcode

包含两列的索引主要用于将两列用作过滤器表达式的一部分的过滤器。例如:Name = 'NameValue' AND Barcode = 'BarcodeValue'。考虑索引中每一列的顺序位置也很重要。例如,假设您创建了此索引: CREATE NONCLUSTERED INDEX NCIX_Product_Name_Barcode ON Product (Name,Barcode); 使用过滤器表达式的查询Name = 'NameValue'仍然可以查找此索引,因为Name它是索引中的第一列,但使用过滤器表达式的查询Barcode = 'BarcodeValue'不能。

在对索引设计做出任何长期决策之前,您应该首先熟悉 Microsoft 在通用索引设计指南中发布的指南

最后,如果您确实需要搜索Nameor以查找Barcode字符串匹配项,您应该查看 Microsoft 的全文索引文档,这可能是您以这种方式进行索引搜索的最佳解决方案。


推荐阅读