のパフォーマンスが ほどよくselect * from table
ないのはなぜselect col_1,col_2 from table
ですか? 私が理解している限り、返される列の数ではなく、時間がかかるのは行の検索です。
2 に答える
不要な列を選択すると、パフォーマンスに大きな影響を与えるクエリ プランが変更される可能性があります。たとえば、インデックスcol_1, col2
があり、テーブルに他の列がある場合、select *
クエリは完全なテーブル スキャンを実行する必要がありますが、select col_1, col_2
クエリはインデックスをスキャンするだけで済みます。クエリ。複数のテーブルを含むクエリや、ビューに対するクエリを含むクエリの処理を開始する場合、列のサブセットを選択すると、Oracle が不要な結合や関数評価を排除できるようになり、クエリ プランが変更されることがあります。公平を期すために、選択された列に基づいてクエリ プランが変更されることは特に一般的ではありませんが、その場合、その変更はしばしば重要です。
データベース外のアプリケーションから SQL ステートメントを発行している場合、追加の列を選択すると、Oracle はネットワーク経由で追加のデータを送信するように強制されるため、アプリケーションはネットワーク I/O で不要なデータを送信するのを待つ時間が長くなります。これは、アプリケーションが WAN に展開される場合は特に、非常に非効率的です。
不要な列を選択すると、プランを変更せずに、Oracle が追加の I/O を実行するように強制することもできます。たとえば、テーブル内の必要のない列の 1 つが である場合LOB
、Oracle はそのLOB
データを取得するために追加の作業を行う必要があります。データがディスク上の連鎖ブロックに格納されていて、関心のある列がたまたま最初の行ピースにある場合、Oracle は、列のサブセットを指定するクエリのために追加の行ピースをフェッチする必要はありません。一方、 を実行するクエリは、select *
すべての行の断片をフェッチする必要があります。
もちろん、それはメンテナンス面を考える前の話です。PL/SQLの外部でアプリケーションを作成している場合、これを行うSELECT *
と、将来誰かが新しい列をテーブルに追加したときにコードが壊れるか、アプリケーションが実行時に列のセットを動的に決定する必要があります。新しい列に自動的に対応するために返されます。それは確かに可能ですが、コードがより複雑になり、デバッグと保守がより困難になる可能性があります。PL/SQL を作成し、データを変数にフェッチする場合、本番コードで%ROWTYPE
実行することは完全に合理的です。SELECT *
他の言語では、SELECT *
.
SELECT * を実行するときに、テーブルのデータ ディクショナリから定義を検索するという問題があります。
また、必要な列が col_1 と col_2 だけの場合、データベースが必要以上の作業を行うという問題もあります。これは、特に大きなテーブルで問題になります。
また、ネットワーク帯域幅が、必要以上に大きなデータセットによって不必要に飲み込まれてしまうという問題もあります。
SELECT * を実行するのはベスト プラクティスではありません。また、埋め込み SQL コードが読みにくくなります。