Настройка производительности при поиске строк с использованием PATINDEX. - PullRequest
0 голосов
/ 22 ноября 2018

У меня следующий запрос для поиска строки с использованием 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
Данные: 10 миллионов
ИНДЕКС: [Номер сотрудника], [Имя сотрудника], [Фамилия сотрудника]

Статистика:

Запрос: Выше запроса
Строки: 90,505
Время выполнения: 00: 02: 45

1 Ответ

0 голосов
/ 22 ноября 2018

Вы можете попробовать добавить в запрос предложение 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

Кроме того, если вы можете добавить индексы, вы можете добавить индексы для first и last назовите и попробуйте сначала выбрать только те строки, которые нужно вернуть:

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];

Даже если вам не разрешено полагаться на порядок индексов, вы будете работать с меньшим количеством данных, когда индексычитать (вам нужно только прочитать все идентификаторы пользователей, имена и фамилии. Затем, имея идентификаторы, просто отфильтруйте кластерный индекс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...