Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
神谷 雅紀
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 と呼ばれます。
変数とパラメータの違い
以上のとおり、クエリ実行の観点では、変数はクエリの最適化には使用できませんが、パラメータは使用できるという点が異なります。