2009-05-11 20 views
2

このクエリは、長い時間がかかっているendDateにはnullであるこのステートメントをより速くするには: "paramDateとstartDateとNULLの間"? endDateにはnullのとき

私が使用する必要がありますどのような
SELECT * 
FROM HastaKurumlari 
WHERE CONVERT(SMALLDATETIME,'21-05-2009',103) 
BETWEEN startDate 
    AND (CASE WHEN endDate IS NULL THEN GETDATE() ELSE endDate END) 

は、より速くそれを作るために(私はそのcase文について、case文の前にそれが速かったと思いますか)?

答えて

1

はCONVERTまたはCASEなしクエリです:

SELECT * 
FROM HastaKurumlari 
WHERE '21-05-2009' between startDate and IsNull(endDate,getdate()) 

SQL Serverが(GETDATEを評価doens'tを確認するために)私は、SQL Serverがスマートであるかなり確信しているが、行ごとに、あなたは、それをキャッシュすることができデフォルトで十分:クエリプランを投稿

declare @now datetime 
set @now = getdate() 

SELECT * 
FROM HastaKurumlari 
WHERE '21-05-2009' between startDate and IsNull(endDate,@now) 

は、クエリが遅い理由を説明するのに役立つことができます:

SET SHOWPLAN_TEXT ON 
go 
SELECT * 
FROM HastaKurumlari 
WHERE CONVERT(SMALLDATETIME,'21-05-2009',103) 
BETWEEN startDate 
    AND (CASE WHEN endDate IS NULL THEN GETDATE() ELSE endDate END) 
+0

これは、結合関数よりも簡単で、以前よりも簡単です。しかし、有用な機能を併合する。 – uzay95

+0

CoalesceとIsNUllの唯一の違いは、Coalesceが3つ以上の引数を取ることができることです。 Coalesce(null、null、3)は、たとえば3を返します。 – Andomar

+3

@Andomar:正しくはない:セマンティクスはわずかに異なります。 COALESCEは '最も高い'データ型に昇格しますが、ISNULLは最初に見つかったデータ型を使用します。また、標準SQLであるCOALESCEは移植性が高くなります。それについて言えば、私はgetdate()よりもCURRENT_TIMESTAMPを好む。 – onedaywhen

1

あなたはcoalesce機能を試すことができます:

select * 
from HastaKurumlari 
where convert(smalldatetime, '21-05-2009', 103) 
    between startDate and coalesce(endDate, getdate()); 

特定可能にする唯一の方法は、いずれかの選択肢を試してみて、各クエリのために生成された実行計画を表示することです。

+0

指定された日付が現在の日付より前でendDateがnullの場合、2番目の方法はまったく同じように機能しません。最初のレコードにはレコードが含まれ、2番目のレコードにはレコードが含まれません。 – tvanfosson

+0

ああ、あなたは正しいです! 2番目の例が削除されました... –

+0

はい、あなたの答えはあなたのアンドリューに感謝します。 – uzay95

1

パフォーマンスが重要な場合は、オープンエンド日にnullを使用しないでください。サポートされている最大のdatetimeを代わりに使用してください(多分9秒)。

私はまた、別途変換を行いたい:

DECLARE @when datetime 
SET @when = CONVERT(SMALLDATETIME,'21-05-2009',103) 

SELECT * 
    FROM HastaKurumlari 
WHERE @when 
BETWEEN startDate AND endDate 

上記と元のビット別の何かがまだあります。 の意味をGETDATE()の説明で説明できれば、少しきちんと(読む:修正)できるかもしれません。ここで

+0

私は、SQL Serverが "in-query"変換に気付き、テーブルまたはインデックススキャンの前に一度だけそれを実行するほどスマートだと考えました。 –

+0

GETDATE()はendDateを設定するのに適しています。しかし、私は過去にクエリする場合、私はいつまたはDateAdd(d、1、@ When)にendDateを設定する必要があります。しかし、まだこのクエリは実行できません。私たちのendDateはまだNULLです。 – uzay95

+0

@Andrew - 明示的にする方が簡単です。覚えておくことが少なくなります... –

1

出発点として、GETDATE()を除外して、その呼び出しが一度だけ呼び出され、速度の向上が見られるはずです。

あなたが書いたとおりに、enddateがnullのたびにGETDATE()を評価するように求めています。

GETDATE()はnon-deterministic関数なので、クエリは最適化できず、実行される傾向があります。

+0

ちょうど1つ以上のmilion行でgetdate()を使ったクエリを実行しましたが、キャッシュされた日付を使用したものと同じ速さでした。 – Andomar

+0

@Andomarは使用したコードを投稿しますか? –

関連する問題