変数とパラメータの違い

 

神谷 雅紀
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 と呼ばれます。

 

変数とパラメータの違い

以上のとおり、クエリ実行の観点では、変数はクエリの最適化には使用できませんが、パラメータは使用できるという点が異なります。