web-dev-qa-db-ja.com

COALESCEとISNULLのパフォーマンスの違い?

多くの人がISNULLの代わりにCOALESCE関数を使用するのを見てきました。インターネット検索の結果、COALESCEはANSI標準であることがわかりました。そのため、COALESCEを使用するときに何が期待できるかがわかっているという利点があります。ただし、ISNULLの方がより明確に見えるため、ISNULLの方が読みやすいようです。

また、ISNULLは、データベースサーバーや言語によって動作が異なるため、注意が必要です。

これらすべては、私の考えでは、スタイルと標準に要約されます。そのスタイルが主観的であることを考えると、ISNULLではなくCOALESCE(またはその逆)を使用する理由はありますか?具体的には、どちらか一方のパフォーマンス上の利点はありますか?

51
Richard

COALESCEは内部でCASE式に変換され、ISNULLは内部エンジン関数です。

COALESCEはANSI標準関数、ISNULLはT-SQLです。

パフォーマンスの違いは、選択が実行プランに影響を与えるときに発生する可能性があり、実際に発生しますが、 生の関数速度の違いはごくわずかです

28
  • ISNULLはSybase/SQL Server固有です
  • COALESCEはポータブルです

その後

  • ISNULLは2つの引数を取ります
  • COALESCEは1-n個の引数を取ります

最後に、楽しいビットです。結果のデータ型と長さ/精度/スケール

  • ISNULLは最初の引数と同じです
  • COALESCEは datatype precedence に従って最高です

この最後のビットは、ISNULLがより予測可能(?)であり、COALESCEが意図しないデータ型変換を追加する可能性があるため、通常はNULLが使用される理由です。

DECLARE @len10 varchar(10); --leave it NULL
SELECT
    ISNULL(@len10, '0123456789ABCDEF'),     -- gives 0123456789
    COALESCE(@len10, '0123456789ABCDEF');   -- gives 0123456789ABCDEF

すべてのデータ型が同じであるため、実用的な違いはありません...

42
gbn

Markが指摘したように、パフォーマンスの違いを見つけるのは困難です。他の要素がもっと重要になると思います。私にとっては、私は常にCOALESCEを使用します。これのほとんどは、あなたまたはマークによってすでに言及されています。

  • COALESCEはANSI規格です。コードを移植する場合、心配する必要のあることが1つ少なくなります。私にとって個人的にはこれはそれほど重要ではありません。そのようなポートが実際にセルコの教室の世界の外で実際に発生する頻度は低いためですが、一部の人にとってはこれは利点です。
  • 読みやすさについてあなたが言ったこととは対照的に、ISNULLがブール値を返す他の言語やプラットフォームから来たユーザーにとっては特に、ISNULLを読むのが難しいことがわかります( SQL Serverには存在しません)。確かに、COALESCEは綴りが難しいですが、少なくともそれが誤った仮定につながることはありません。
  • COALESCEはもっと柔軟です。COALESCE(a、b、c、d)と言えますが、ISNULLを使用すると、同じことを実現するために多くのネストを行う必要があります。

また、異なるデータ型/精度などで使用する場合は、2つの関数を使用してデータ型の優先順位がどのように処理されるかを理解しておく必要があります。

例外が1つあります。これらは、SQL Serverの現在のバージョンでは異なる方法で処理されます。

SELECT COALESCE((SELECT some_aggregate_query),0); 

SELECT ISNULL((SELECT some_aggregate_query),0); 

COALESCEバリアントは実際にsome_aggregate_queryを2回実行します(値を確認するために1回、ゼロ以外の場合は1回返す)一方で、ISNULLはサブクエリを1回だけ実行します。ここで他のいくつかの違いについて話します:

24
Aaron Bertrand