使用PATINDEX对字符串搜索进行性能调整。

时间:2018-11-22 05:39:05

标签: sql-server tsql sql-server-2008-r2

我有以下查询,使用PATINDEX搜索字符串。

查询:

SELECT [Employee First Name],[Employee Last Name],[Employee Middle Name],[Gender]............
FROM OPENQUERY([LinkDB],'SELECT [Employee First Name],[Employee Last Name],[Employee Middle Name],[Gender]............ FROM [LinkDB].dbo.[Employee]') 
WHERE ISNULL(PATINDEX('%Jack%',[Employee First Name]),'0') + ISNULL(PATINDEX('%Jack%',[Employee Last Name]),'0')  >= '1'

数据详细信息:

  

数据库:LinkDB
  列:60
  数据:1000万
  索引:[员工编号],[员工姓氏],[员工姓氏]

统计数据:

  

查询:以上查询
  行:90,505
  花费时间:00:02:45

1 个答案:

答案 0 :(得分:1)

您可以尝试将WHERE子句添加到查询中。注意,我对代码进行了一些更改以使其适用于我的环境:

SELECT *
FROM OPENQUERY([RMVNSQL01\INST1],'SELECT  [login], [FirstName], [LastName] FROM [smModel_20180807_UpdateTests_CORE].dbo.[SecurityUsers]') 
WHERE ISNULL(PATINDEX('%emil%',[FirstName]),'0') + ISNULL(PATINDEX('%emil%',[LastName]),'0')  >= '1'

SELECT *
FROM OPENQUERY([RMVNSQL01\INST1],'SELECT  [login], [FirstName], [LastName] FROM [smModel_20180807_UpdateTests_CORE].dbo.[SecurityUsers] WHERE ISNULL(PATINDEX(''%emil%'',[FirstName]),''0'') + ISNULL(PATINDEX(''%emil%'',[LastName]),''0'')  >= ''1''') 

您可以看到,在您的情况下,我们进行了远程扫描,然后进行了过滤。在第二个中,缺少过滤器通过:

enter image description here

此外,如果您可以添加索引,则可以在firstlast名称上添加索引,然后尝试首先仅选择需要返回的行:

CREATE TABLE #EmployeesFiltered 
(
    [EmployeeID] INT 
);

INSERT INTO #EmployeesFiltered ([EmployeeID])
SELECT [EmployeeID]
FROM [LinkDB].dbo.[Employee]
WHERE ISNULL(PATINDEX('%Jack%',[Employee First Name]),'0') + ISNULL(PATINDEX('%Jack%',[Employee Last Name]),'0')  >= '1';

SELECT *
FROM [LinkDB].dbo.[Employee] A
INNER JOIN  #EmployeesFiltered B
    ON A.[EmployeeID] = B.[[EmployeeID];

即使不允许您依赖索引的顺序,在读取索引时,您也将使用较少的数据量(您只需要读取所有用户的ID,名字和姓氏即可。然后仅拥有ID)过滤聚簇索引。