2015-10-08 3 views
0

Я пытаюсь оптимизировать хранимую процедуру, которая на данный момент медленная. Для поиска требуется несколько параметров, которые могут быть нулевыми. Запрос внутри SP выглядит следующим образом.Оптимизация запросов SQL (поиск)

SELECT 
    *some fields from the table* 
FROM 
    [hrmCase] 
WHERE 
    BrkId = @BrkId 
AND 
    (ChannelId IN ('TO','TD')) 
AND 
    case 
     when @PsId is null then 1 
     when (@PsId is not null) and ((SELECT SUBSTRING(UPPER(DATENAME(MONTH, Created)),1,3) + CAST(PSId AS varchar) PSId) like ('%' + @PsId + '%')) then 1 else 0 
    end = 1 
AND 
    case 
     when @ACaseId is null then 1 
     when (@ACaseId is not null) and (AId like ('%' + @ACaseId + '%')) then 1 else 0 
    end = 1 
AND    
    case 
     when @DateCreated is null then 1 
     when (@DateCreated is not null) and (dbo.StripTime(Created) = dbo.StripTime(@DateCreated)) then 1 else 0 
    end = 1 
AND 
    case 
     when @Clients is null then 1 
     when (@Clients is not null) and (Client like ('%' + @Clients + '%')) then 1 else 0 
    end = 1 

Это лучший способ сделать это, или я должен построить динамический запрос на основе входных параметров, как показано ниже

Declare @SQLQuery AS NVarchar(4000) 
Declare @ParamDefinition AS NVarchar(2000) 

Set @SQLQuery = 'SELECT *some fields from the table* FROM [hrmCase] WHERE (1=1)' 

If @PsId Is Not Null 
    Set @SQLQuery = @SQLQuery + ' And (SELECT SUBSTRING(UPPER(DATENAME(MONTH, Created)),1,3) + CAST(PSId AS varchar) PSId) like (''%''' + @PsId + '''%'')' 

etc.. 

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

Приветствия, DS

+0

В каждом случае вы используете функцию или 'LIKE% фраза%', поэтому ваш запрос не является SARGable, а оптимизатор запросов не будет использовать idexes, если он существует. Нет использования индексов = низкая производительность. – lad2025

+0

Динамический запрос почти всегда лучше, когда условия могут использовать индексы. В вашем случае условия не могут. Таким образом, динамическая версия будет немного быстрее, потому что запрос будет иметь меньшее количество сложных сравнений. Но это, вероятно, не будет иметь большого значения. –

+0

не может с этим поделать. Большинство столбцов являются текстовыми столбцами, и мы разрешили частичный поиск. – SkoolCodeian

ответ

0

SQL Server очень плохо дело с параметрами, как это - было много Мы сумели случаи, когда мы получаем его работу благоугодно, а затем через 4 месяца, что-то изменения, и она превращается в таблицу сканирование (или хуже - я видел производительность FAR хуже, чем просто сканирование таблицы) снова и снова. (У нас есть база данных 1.5 ТБ на SSD на зеркальных 40 основных серверах). Лучшим решением, которое мы нашли, является использование отдельных хранимых процедур или использование динамического SQL. Многие «эксперты» недовольны динамическим SQL, но реальность такова, что в любой приличной среде в наши дни перекомпиляция динамического SQL незначительна с точки зрения использования процессора и задержки производительности, и устраняет типы проблем, которые вы видите, потому что вы устраняете условия в предложениях WHERE, которые путают оптимизатор запросов.

Ведущие подстановочные знаки также приведут к сканированию таблиц в каждом случае. Полнотекстовая индексация может выполнять этот тип поиска гораздо эффективнее обычного SQL. Некоторые особенности SQL Server поддерживают полнотекстовое индексирование и запросы, а некоторые нет.

Смежные вопросы