У меня есть база данных 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%'))
, который был упомянут как решение в в этом вопросе, но это не имело значения.
Любая помощь будет принята с благодарностью.