2012-02-17 23 views
2

以下の2つのクエリのうち、どちらが高速ですか?この表には100M以上のレコードが含まれています。だから私は、where句でISNULLを使用するのが最初に変数に値を代入し、where句で変数を使用するのと同じであるかどうかを知りたいだけです。日付範囲クエリ方法のパフォーマンス比較

declare @dt datetime 
select COUNT(*) from pandl 
    where PaymentDate >= ISNULL(@dt, convert(nvarchar(10),getdate(), 121)) 

select @dt = ISNULL(@dt, convert(nvarchar(10),getdate(), 121)) 
select COUNT(*) from pandl 
    where PaymentDate >= @dt 
+7

両方を実行してどちらが高速であるか確認しましたか? SQLプロファイラを使用して各クエリの実行計画を確認しましたか? – Pondlife

+0

「今」のいくつの異なる値を使用しますか? 2つ目のクエリは、必要に応じて現在の日付/時刻を1回キャプチャしてから検索します。 – HABO

+1

@ user92546それは良い点ですが、最初のクエリの途中で 'getdate()'が複数回評価されても(私は検証するためにいくつかのテストを実行する必要があります)、変換がラウンドするので真夜中の前にクエリが開始されていて、真夜中後にまだ処理していた(そして新しい値を 'getdate()'に代入しているかどうかは本当に問題になります)。私はあなたに一度気に入っていることに一度気に入っていますが、それが本当に悪い時には「ベストではない」と明確にしたいと思っています。 –

答えて

2

2番目の方が良いでしょう。 where句の関数を呼び出すと、クエリオプティマイザはシークの代わりにスキャンを使用します。言い換えれば、理想的でない実行計画を得るでしょう。

+0

+1 Hola Brandon! –

+2

'where'句から*チェックしている値に関数*を呼び出すと、確実にスキャンが行われます。しかし、私は、呼び出しの寿命を通じて戻り値が変化しなければ、SQL Serverが関数を一度呼び出すことが十分に分かっているという印象を受けました。 – cHao

+0

@cHaoはい、これは本当です。問題のどちらのバージョンでもスキャンが行われません。私は彼の最初の文に同意したので、私はBrandonに彼の最初の+1を与えていました。 :-) –

2

文字列への変換を少し高価にするのではなく、少し小さいデータ型を使用してあなただけの一日の境界を気が「t)は、サブ分単位を必要とする:

DECLARE @dt SMALLDATETIME; 
SET @dt = DATEADD(DAY, DATEDIFF(DAY, '19000101', CURRENT_TIMESTAMP), '19000101'); --* 

SELECT COUNT(*) FROM dbo.pandl 
    WHERE PaymentDate >= @dt; 

あなたは文字列への変換を引き続き使用するつもりなら、CHAR(10)を使用する - 私はスタイル121がために起こっているとは思いませんUnicodeサポートが必要な日付形式を生成します。

*はい、あなたは、DATE

1

FWIWのような新しいタイプの外DATEADDではなくせずにこれを行うことができますが、インデックスを持っていない場合、計画に影響を与えるつもりはないされています。テキストモードで

http://data.stackexchange.com/stackoverflow/query/61684/http-stackoverflow-com-questions-9329461-ms-sql-query-performance

ランは、ショーの実行計画を確認してください。

StackExchangeのこれらの日付列の1つに索引があるとわかりましたが、見つからなかった。

これ以外の回答もあります。nvarcharを不必要に使用しないでください。正当な理由で日付を文字列に変換しないでください。クエリの外でより見やすく評価できる関数を使用しないでください。クエリの中で(必要でない場合は、クエリ内の関数をまったく使用しないでください)。

+0

+1は実際の実行計画を示しています! – Justin

関連する問題