Производительность SQL Server параметризованных запросов с ведущими подстановочными знаками

У меня есть база данных SQL 2008 R2 с примерно 2 миллионами строк в одной из таблиц, и я испытываю трудности с выполнением определенного запроса при использовании параметризованного SQL.

В таблице есть поле, содержащее имя:

У меня есть база данных SQL 2008 R2 с около 2 миллионами строк в одной из таблиц, и я испытываю трудности с выполнением определенного запроса при использовании параметризованного SQL.

В таблице есть поле, содержащее имя:

У меня есть база данных SQL 2008 R2 с около 2 миллионами строк в одной из таблиц, и я испытываю трудности с выполнением определенного запроса при использовании параметризованного SQL.

В таблице есть поле, содержащее имя:

[PatientsName] nvarchar NULL,

На поле также есть простой индекс:


CREATE NONCLUSTERED INDEX [IX_Study_PatientsName] ON [dbo].[Study] 
(
    [PatientsName] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [INDEXES]
GO

Когда я выполняю этот запрос в студии управления, выполнение занимает около 4 секунд:


declare @StudyPatientsName nvarchar(64)
set @StudyPatientsName= '%Jones%'

SELECT COUNT(*) FROM Study WHERE Study.PatientsName like @StudyPatientsName

Но, когда я выполняю этот запрос:


SELECT COUNT(*) FROM Study WHERE Study.PatientsName like '%Jones%'

требуется чуть больше половины секунды для выполнения.

Глядя на планы выполнения, запрос без параметризации выполняет сканирование индекса с использованием вышеупомянутого индекса, что, очевидно, является эффективным. Параметризованный запрос использует индекс, но выполняет поиск диапазона по индексу.

Частично проблема заключается в использовании символа подстановки. Когда я удаляю подстановочный знак, оба запроса возвращаются за доли секунды. К сожалению, мне нужно поддерживать ведущие символы подстановки.

У нас есть доморощенный ORM, который выполняет параметризованные запросы, где возникла проблема. Эти запросы выполняются на основе ввода от пользователя, поэтому параметризованные запросы имеют смысл избегать таких вещей, как атака с использованием SQL-инъекций. Мне интересно, есть ли способ сделать функцию параметризованного запроса так же, как и не параметризованный запрос?

Я провел некоторое исследование, изучая различные способы давать подсказки оптимизатору запросов, пытаясь заставить оптимизатор Повторите план запроса для каждого запроса, но пока не нашли ничего, что улучшило бы его производительность. Я попробовал этот запрос:


SELECT COUNT(*) FROM Study WHERE Study.PatientsName like @StudyPatientsName
OPTION ( OPTIMIZE FOR (@StudyPatientsName = '%Jones%'))

, который был упомянут как решение в в этом вопросе, но это не имело значения.

Любая помощь будет принята с благодарностью.

6
задан Community 23 May 2017 в 10:33
поделиться