変数とパラメータの違い
神谷 雅紀
Escalation Engineer
2ヶ月ほど前に、「DO’s&DONT’s #10: やらない方がいいこと - クエリの条件句で変数を参照する」というタイトルで、クエリの条件句で変数を使用することは避け、変数の変わりにパラメータを使用した方がよいという内容を投稿しましたが、変数とパラメータが混同されていることがあるようですので、今回は、変数とパラメータの違いについて説明します。
変数とは
変数 (variable, local variable) は、declare によって宣言され、declare、SET、SELECT ステートメントによって値が設定されます。
変数の例 : 青字が変数
-- 変数宣言
declare @local_variable_1 nvarchar(10)
declare @local_variable_2 nvarchar(10) = ‘abc’ -- 宣言と同時に値の設定 -- 値の設定
set @local_variable_1 = ‘abc’ select * from db1.sch1.tab1 where col1 = @local_variable_1
実際に変数に値が設定されるのは、コンパイルやクエリの最適化時ではなく、値を設定するステートメントの実行時です。上の例では、select * from db1.sch1.tab1 where col1 = @local_variable_1 がコンパイルおよび最適化される時には、@local_variable_1 は未知の値です。
パラメータとは
パラメータ (parameter) は、ストアドプロシージャやパラメータ化クエリ (parameterized query) を実行する際に、ストアドプロシージャやパラメータ化クエリに対して渡される値です。
パラメータの例 : 青字がパラメータ
-- パラメータ化クエリの実行
sp_executesql @statement=N’select * from db1.sch1.tab1 where col1 = @param1’,@params=N’@param1 nvarchar(10)’,@param1=N’abc’ -- ストアドプロシージャ作成
create proc sch1.proc1 @param1 nvarchar(10)
as
select * from db1.sch1.tab1 where col1 = @param1 -- ストアドプロシージャ実行
exec sch1proc1 @param1=’abc’
パラメータは、コンパイル時には値が設定されています。そのため、クエリは、パラメータに設定されている値を用いて最適化されます。
上の例では、クエリ select * from db1.sch1.tab1 where col1 = @param1 は、@param1 に指定されている値を用いて最適化されます。パラメータに指定されている値を用いてクエリの最適化が行われる動作は、Parameter Sniffing と呼ばれます。
変数とパラメータの違い
以上のとおり、クエリ実行の観点では、変数はクエリの最適化には使用できませんが、パラメータは使用できるという点が異なります。