2012-02-17 6 views
4

2つの列を持つCARテーブルを1つ仮定します。CAR_ID (int)およびVERSION (int)VS over Partitionによる比較グループ

各車の最大バージョンを取得します。

だから、(少なくとも)2つの解決策があります。

select car_id, max(version) as max_version 
    from car 
group by car_id; 

または:

select car_id, max_version 
    from (select car_id, version 
       , max(version) over (partition by car_id) as max_version 
      from car 
       ) max_ver 
where max_ver.version = max_ver.max_version 

は、同様にパフォーマンスの高いこれらの2つのクエリはありますか?

答えて

2

はい影響を受ける可能性があります

2番目のクエリはインラインビューの例です。 これは、さまざまな種類の集計や集計関数を使用してレポートを実行するための非常に便利な方法です。

Oracleはサブクエリを実行し、結果の行をFROM句のビューとして使用します。

パフォーマンスについては、別のサブクエリタイプを選択するのではなく、常にインライン表示を推奨します。

もう1つの2番目のクエリはすべての最大レコードを与えますが、最初のレコードは最大レコードが1つだけです。

see here

+2

"さらに2番目のクエリではすべての最大レコードが得られますが、最初は最大レコードが1つのみです。"私は最初の列が1つの最大値を返すと書いた理由を理解していません。 2つのクエリは同じ結果を返します – Mik378

2

それはあなたのインデックススキームとテーブル内のデータの量に依存します。オプティマイザは、実際にテーブル内にあるデータに基づいて異なる決定を下す可能性が高くなります。

オプティマイザは、GROUP BYクエリ対BYクエリPARTITIONとの完全スキャンを実行する可能性が高いこと(私はあなたがオラクルについて尋ね知っている)は、少なくともSQL Serverで、私を発見しました。しかし、CAR_IDとVERSION(DESC)が含まれている索引がある場合のみです。

ストーリーのモラルは、私が徹底的にテストして正しいものを選ぶということです。小さなテーブルの場合は問題ありません。本当に、本当に大きなデータセットの場合、どちらも速いかもしれ...

2

は、私は、これは非常に古いです知っているが、それは指摘されるべきであると思いました。あなたがそのようにオプション2をやった理由は...このケースでは、あなたと同じテーブルの2倍から選択してからは、自分自身に戻って結果を結合しているため、理論的に遅くする必要があります選択サブ

select car_id, max_version 
    from (select car_id 
      , version 
      , max(version) over (partition by car_id) as max_version 
      from car) max_ver 
where max_ver.version = max_ver.max_version 

わかりません。

インラインビューからバージョンを削除するだけで同じことができます。

select car_id, max(version) over (partition by car_id) as max_version 
    from car 

パフォーマンスは実際にはこの状況でオプティマイザに依存しますが、元々の答えは狭い結果を示すインラインビューを示唆しています。これは、与えられた選択肢でフィルタなしとの同じテーブルに良い例ではないですけど。あなたは列の多くを選択しますが、結果セットに合わせてさまざまな集計を必要としているとき

パーティションにも便利です。それ以外の場合は、他の列ごとにグループ化する必要があります。

関連する問題