私は約1,000万行の大きなテーブルで検索しています。私は開始日と終了日を指定し、それらの日付の間に作成されたテーブル内のすべてのレコードを返したいと思います。作成したDATETIME列のDATETIME検索述語が文字列のリテラル述語よりもはるかに遅い
declare @StartDateTime datetime = '2016-06-21',
@EndDateTime datetime = '2016-06-22';
select *
FROM Archive.dbo.Order O WITH (NOLOCK)
where O.Created >= @StartDateTime
AND O.Created < @EndDateTime;
は、非クラスタ化インデックスを持つDATETIME列です:
それはストレートなクエリです。
このクエリには約15秒かかりました。
declare @StartDateTime datetime = '2016-06-21',
@EndDateTime datetime = '2016-06-22';
select *
FROM Archive.dbo.Order O WITH (NOLOCK)
where O.Created >= '2016-06-21'
AND O.Created < @EndDateTime;
が唯一の変更は、文字列リテラルで@StartDateTime
検索述語を交換されて次のように私は、少しのクエリを変更した場合
はしかし、それは同じ結果を返すことだけ1秒かかります。実行計画を見て、私が@StartDateTime
を使用したときにインデックススキャンを行いましたが、文字列リテラルを使用したときにインデックスシークを行い、15倍高速でした。
誰もがなぜ文字列リテラルを使用するのがとても速いのか知っていますか?
DATETIME列とDATETIME変数の比較は、列を日付の文字列表現と比較するよりも速いと考えていました。私は作成された列のインデックスを削除して再作成しようとしましたが、それは何の違いもありませんでした。私はテストシステムと同じようにプロダクションシステムで同様の結果を得ているので、奇妙な動作は特定のデータベースやSQL Serverインスタンスに固有のように見えません。
答えはSQL Serverがクエリで変数をどのように認識するかに関係しています。 SQLがクエリを実行する前に変数が何であるかを知ることができない場合、キャッシュされたプランを使用することができないか、新しいものを効果的に推測できない可能性があります。 –
件名にSQLmagの有益な記事があります。[SQLmag最適化変数とパラメータ](http://m.sqlmag.com/t-sql/optimizing-variables-and-parameters) –
@clifton_h:申し訳ありませんが、それはしばらく時間がかかりました。あなたがリンクしたその記事は私の質問に答えます。あなたのコメントを答えに変えたいなら、私はそれを受け入れます。 –