Допустим, это данные, которые вы работаете с:
-- 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);
Я удалил теги базы данных, которые вы добавили, поскольку вы явно не используете MySQL и SQL-сервер. Пожалуйста, добавьте только тег для RDMS, который вы используете. –
Откуда берутся 'EmployeeID' и' Name'? Являются ли они столбцами в вашей таблице «Сотрудник»? –
Вы можете создать дерево 'if' /' then'/'else' с 16 возможными вариантами условий поиска и выполнить соответствующий запрос. Или соберите имя хранимой процедуры на основе критериев поиска и выполните SP. В любом случае вы можете использовать предварительно скомпилированный «оптимальный» запрос. Кроме того: действительно ли вы собираетесь рассматривать все столбцы и отклонять любую строку, содержащую значение «NULL»? Если нет, вам нужно что-то вроде 'case when (@Name - NULL или @Name = '') или (Name = @Name), затем 1 else 0 end = 1'. – HABO