代码之家  ›  专栏  ›  技术社区  ›  MAK

转换为可搜索查询

  •  0
  • MAK  · 技术社区  · 7 年前

    我想写一个查询来搜索表中包含的字符串。

    表:

    Create table tbl_sarg
    (
        colname varchar(100),
        coladdres varchar(500)
    );
    

    注:我只想使用 Index Seek 搜索了3亿条记录。

    索引:

    create nonclustered index ncidx_colname on tbl_sarg(colname);
    

    样本记录:

    insert into tbl_sarg values('John A Mak','HNo 102 Street Road Uk');
    insert into tbl_sarg values('Shawn A Meben','Church road USA');
    insert into tbl_sarg values('Lee Decose','ShopNo 22 K Mark UK');
    insert into tbl_sarg values('James Don','A Mall, 90 feet road UAE');
    

    问题1:

    select * from tbl_sarg
    where colname like '%ee%'
    

    实际执行计划:

    enter image description here

    问题2:

    select * from tbl_sarg
    where charindex('ee',colname)>0
    

    实际执行计划:

    enter image description here

    问题3:

    select * from tbl_sarg
    where patindex('%ee%',colname)>0
    

    实际执行计划:

    enter image description here

    如何强制查询处理器在大数据集上使用索引查找而不是表/索引扫描?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Geovanny Hernandez    7 年前

    根据定义,您发布的所有查询都不是可搜索的,例如,“…%”的使用自动强制查询引擎进行扫描,另一种情况是在谓词中的列中使用函数(如charindex或patindex)。

    以下是一些帖子: https://bertwagner.com/2017/08/22/how-to-search-and-destroy-non-sargable-queries-on-your-server/

    Kimberly Tripp写了非常有趣的文章,如果您必须使用通配符执行这种查询,那么可能值得检查一下使用FullTextSearch功能的可能性。我的意思是,或者你的极限,在你的疑问中做一个精确的谓词,否则你将不得不改变策略,几乎忘记,不要试图用暗示强迫使用Seek,我看不出这种药会比疾病更好。

        2
  •  1
  •   Community Mohan Dere    6 年前

    搜索参数,简称SARG,是一个过滤器谓词,使优化器能够依赖它 索引顺序。筛选器谓词使用以下形式(或带有两个分隔符的变量) 范围,或操作数位置翻转时): 哪里 <column> <operator> <expression>

    这样的过滤器非常有用 如果:

    1. 不能对过滤列应用操作。

    2. 运算符标识索引中连续范围的符合条件的行。这就是问题所在 运算符的大小写,如=,>>=<<=,介于之间,比如带有已知前缀,等等。 像<>,比如用通配符作为前缀。

    在大多数情况下,当您对过滤列应用操作时,优化器不会这样做 尽量聪明一点,理解计算的意义,如果索引排序 仍然可以信赖。它只是假设结果值的排序可能与 源值,因此索引顺序不可信。

    那么为什么SQL Server不使用 %ee% 查询假设你手里拿着一本电话簿,我让你找到每个姓氏包含字母%ee%的人。你必须扫描电话簿中的每一页,因为结果将包括以下内容:

    • 李勇

    • 凯思莉

    • 艾琳

      当我问你所有的姓氏 %ee%

    那就是 进来。