パーティションによる対比較グループ
-
27-10-2019 - |
質問
1つのテーブルを仮定します CAR
2つの列付き CAR_ID (int)
と VERSION (int)
.
各車の最大バージョンを取得したいです。
したがって、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番目のクエリは、インラインビューの例です。これは、さまざまな種類のカウントを使用してレポートを実行したり、総関数を使用したりするための非常に便利な方法です。
Oracleはサブクエリを実行し、結果の行をFrom句のビューとして使用します。
パフォーマンスについて考慮するように、別のサブクエリタイプを選択する代わりに、常にインラインビューを推奨してください。
もう1つの2番目のクエリはすべてのMaxレコードを提供しますが、最初のレコードは1つのMAXレコードのみを提供します。
他のヒント
私はこれが非常に古いことを知っていますが、指摘されるべきだと思いました。
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を行ったのかわからない...この場合、サブセレクトは、同じ表2Xから選択し、結果をそれ自体に結合するため、理論的に遅くする必要があります。
インラインビューからバージョンを削除するだけで、それらは同じです。
select car_id, max(version) over (partition by car_id) as max_version
from car
この状況では、パフォーマンスは実際にはオプティマイザーに依存しますが、はい、元の答えとして、結果が狭い結果になるとインラインビューを示唆しています。これは良い例ではありませんが、選択された選択にフィルターがないのと同じテーブルです。
多くの列を選択しているが、結果セットに適合するさまざまな集約が必要な場合には、パーティション化も役立ちます。そうしないと、他のすべての列でグループ化することを余儀なくされます。
インデックス作成スキームとテーブル内のデータの量に依存します。オプティマイザーは、実際にテーブル内にあるデータに基づいて異なる決定を下す可能性があります。
少なくともSQL Server(Oracleについて尋ねたことは知っている)では、Optimizerがクエリごとにパーティションで完全なスキャンを実行する可能性が高いことを発見しました。しかし、それはあなたがその中にcar_idとバージョン(DESC)を含むインデックスがある場合にのみです。
物語の教訓は、私が正しいものを選択するために徹底的にテストすることです。小さなテーブルの場合、それは問題ではありません。本当に、本当にビッグデータセットのために、どちらも高速ではないかもしれません...