sql-server - 如何为 OR 操作创建非聚集索引
问题描述
要求:表Product
有名称和条形码
我想创建一个非聚集索引以使用名称或条形码进行搜索
查询样本
DECLARE @Filter NVARCHAR(100) = NULL
SET @Filter = '%' + ISNULL(@Filter, '') + '%'
SELECT *
FROM Product
WHERE Name LIKE @Filter
OR Barcode LIKE @Filter
请帮助我提供独立于名称和条形码的两个索引或使用一个索引包括名称和条形码的任何解决方案
解决方案
你手头有几个问题。首先,即使存在索引,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 在通用索引设计指南中发布的指南。
最后,如果您确实需要搜索Name
or以查找Barcode
字符串匹配项,您应该查看 Microsoft 的全文索引文档,这可能是您以这种方式进行索引搜索的最佳解决方案。
推荐阅读
- java - 正则表达式匹配某个单词的每次出现但被某些字符打断
- html - 在我的 HTML 页面的前台放置一个 div
- chart.js - Chart.js“minBarLength”没有按预期工作?
- cmake - 运行连接器 C++ 程序时出现疯狂错误
- java - Hibernate 在一对多映射中更新子条目
- sql - 尝试将个人表加入到夫妻表中,提供家庭 ID,而不是让服务器超时
- apache-kafka - Kafka Broker 领导者变更无效
- flutter - Flutter Camera 插件(自动缩放)
- javascript - 删除数据 Javascript
- c - 如何从内核空间中的用户空间指针中正确提取字符串?