のは、これはあなたが作業しているデータだったとしましょう:
-- 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)
があると仮定使用可能なインデックスが存在する - クエリ(または上記のクエリ)は、インデックスシークまたはインデックススキャンとSELECT演算子で構成される基本実行プランを作成します。そのままでクエリを実行するとスキャンします。いずれかのクエリの最後にOPTION(RECOMPILE)を含めるとシークします。インデックスのシークはスキャンよりはるかに優れています。
前述のOPTION(RECOMPILE)ヒントを使用してインデックスシークを取得する代わりに、以下に示すように動的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」はどこから来ますか?彼らはあなたのテーブルの 'Employee'の列ですか? –
16個の可能なバリエーションの検索条件で 'if' /' then'/'else'ツリーを作成し、適切なクエリを実行することができます。または、検索基準に基づいてストアドプロシージャ名をアセンブルし、SPを実行します。どちらの方法でも、事前にコンパイルされた「最適な」クエリを使用できます。脇に:本当にすべての列を調べ、 'NULL'値を含む行を拒否しようとしていますか?もしそうでなければ、 '@NameがNULLか@Name = ''か(Name = @Name)、そして、1 else 0 end = 1'のようなものが必要になります。 – HABO