2016-11-28 2 views
0

У меня есть таблица Employee. ПоляДинамический класс, где класс «CASE» повлияет на производительность

1.EmployeeId, 2.Name, 3.Salary, 4.Address

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

SELECT * FROM Employee 
WHERE 1=1 
AND EmployeeId = CASE WHEN @EmployeeId IS NULL OR LEN(@EmployeeId) =0 THEN EmployeeId ELSE @EmployeeId END 
AND Name = CASE WHEN @Name IS NULL OR LEN(@Name) =0 THEN Name ELSE @Name END 
... 
... 
ORDER BY Name ASC 

@EmployeeId, @name приходят от применения

Может ли сказать мне это будет делать какое-либо влияние на производительность по сравнению с динамическим запросом? или какой из них лучше?

Условие условия where является динамическим. Это не является строгим с условием 2. Несколько раз его 1 или 3 или 4 или 0

Извините за любую опечатку-ошибки

Спасибо заранее.

+1

Я удалил теги базы данных, которые вы добавили, поскольку вы явно не используете MySQL и SQL-сервер. Пожалуйста, добавьте только тег для RDMS, который вы используете. –

+0

Откуда берутся 'EmployeeID' и' Name'? Являются ли они столбцами в вашей таблице «Сотрудник»? –

+0

Вы можете создать дерево 'if' /' then'/'else' с 16 возможными вариантами условий поиска и выполнить соответствующий запрос. Или соберите имя хранимой процедуры на основе критериев поиска и выполните SP. В любом случае вы можете использовать предварительно скомпилированный «оптимальный» запрос. Кроме того: действительно ли вы собираетесь рассматривать все столбцы и отклонять любую строку, содержащую значение «NULL»? Если нет, вам нужно что-то вроде 'case when (@Name - NULL или @Name = '') или (Name = @Name), затем 1 else 0 end = 1'. – HABO

ответ

0

Допустим, это данные, которые вы работаете с:

-- sample data 
USE tempdb; 
GO 
CREATE TABLE dbo.employee (EmployeeId int, Name varchar(100)); 
INSERT dbo.employee 
SELECT TOP (100) 
    ABS(checksum(newid())%10)+1, 
    CASE abs(checksum(newid())%3)+1 WHEN 1 THEN 'Peter' WHEN 2 THEN 'Paul' ELSE 'Mary' END 
    + ' ' + 
    CASE abs(checksum(newid())%3)+1 WHEN 1 THEN 'Smith' WHEN 2 THEN 'Jones' ELSE 'White' END 
FROM sys.all_columns; 

-- A good covering index 
CREATE NONCLUSTERED INDEX nc_employee ON dbo.employee (EmployeeId, Name); 

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

SELECT * 
FROM dbo.employee 
WHERE (EmployeeId = @EmployeeId OR NULLIF(LEN(@EmployeeId),0) IS NULL) 
AND (Name  = @Name  OR NULLIF(LEN(@Name),0)  IS NULL) 

Предположив есть полезный индекс - ваш запрос (или запрос выше) создаст базовый план выполнения, состоящий из поиска индекса или индекса Scan и оператора SELECT. Сканирование, если вы запускаете запрос как есть, искать, если вы включаете OPTION (RECOMPILE) в конце любого запроса ... Индексный поиск намного лучше, чем сканирование.

Альтернативой использованию вышеупомянутого подсказки OPTION (RECOMPILE) для получения поиска индекса будет использование Dynamic SQL, как показано ниже.

DECLARE @EmployeeId int = 5, 
     @Name varchar(100) = 'Peter White'; 

DECLARE @sql nvarchar(2000) = N'SELECT * FROM dbo.employee'; 
DECLARE @ParmDefinition nvarchar(500); 
SET @ParmDefinition = N'@EmployeeId int, @Name varchar(100)'; 

SET @sql += 
CASE 
    WHEN (NULLIF(LEN(@EmployeeId),0) IS NOT NULL AND NULLIF(LEN(@Name),0) IS NOT NULL) 
    THEN ' WHERE EmployeeId = @EmployeeId AND Name = @Name;' 
    WHEN (NULLIF(LEN(@EmployeeId),0) IS NULL AND NULLIF(LEN(@Name),0) IS NOT NULL) 
    THEN ' WHERE Name = @Name;' 
    WHEN (NULLIF(LEN(@EmployeeId),0) IS NOT NULL AND NULLIF(LEN(@Name),0) IS NULL) 
    THEN ' WHERE EmployeeId = @EmployeeId;' 
    ELSE '' 
END; 

EXECUTE sp_executesql @sql, @ParmDefinition, @EmployeeId = @EmployeeId, @Name = @Name; 

Наконец, стоит отметить, что, за исключением случаев, когда @EmployeeID является NULL или пустым, но @name имеет значение - вы получите развертку. Если вы хотите искать в таких случаях, вам нужен другой индекс, который выглядит следующим образом:

CREATE NONCLUSTERED INDEX nc_employee2 ON dbo.employee (Name, EmployeeId); 
+0

Исходный запрос OP отфильтровывает все строки, где 'EmployeeId' или' Name' является 'NULL'. Вы не поддерживали эту функциональность, однако непреднамеренно это было на стороне OP. – HABO

+0

Привет Спасибо за ответ. Но моя проблема в том, что предложение where является динамическим. Если предложение where содержит 1 или 2 или 3 или 4 условия на основе логики приложения. В этом сценарии какой формат будет идеальным?В некоторых случаях условие не наступит. –

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