1. ホーム
  2. sql

[解決済み] select * と select column の比較

2022-07-02 22:53:34

質問

もし、2/3のカラムが必要で、クエリ SELECT * をクエリする場合、I/O やメモリの増減によるパフォーマンスの低下はありますか?

必要なしにselect *を行うと、ネットワークオーバーヘッドが発生する可能性があります。

しかし、select操作において、データベースエンジンは常にディスクからアトミックタプルを引き出すのでしょうか、それともselect操作で要求されたカラムのみを引き出すのでしょうか?

もし常にタプルをプルするのであれば、I/Oオーバーヘッドは同じになります。

同時に、タプルを引き出す場合、タプルから要求された列を取り除くためのメモリ消費もあるかもしれません。

そのため、もしそうであれば、select someColumnはselect *のそれよりも多くのメモリオーバーヘッドを持つことになります。

どうすれば解決するのか?

テーブルが垂直方向に分割されている場合を除いて)常にタプルを引きますので、ご質問の答えとしては、パフォーマンスの観点からは問題ありません。 しかし、他の多くの理由から、(以下では)常に、必要な列を名前によって明確に選択する必要があります。

これは常にタプルを引き出します。なぜなら、(私がよく知るすべてのベンダーの RDBMS において)すべてのもの(テーブルデータを含む)のための基本的なディスク上のストレージ構造は、定義された I/O ページ (例えばSQL Serverでは、各ページは8キロバイトです)。そして、すべてのI/Oの読み取りまたは書き込みは、ページによって行われます。すなわち、すべての書き込みまたは読み取りは、データの完全なページです。

この基本的な構造的制約のため、結果として、データベース内のデータの各行は常に 1 つのページのみに存在しなければなりません。 データの複数のページにまたがることはできません (実際の blob データが個別のページ チャンクに格納され、実際のテーブル行列がポインターを取得するような、blob のような特別なものを除きます)。 しかし、これらの例外はあくまで例外であり、一般的には特殊なケース(特殊なタイプのデータ、または特殊な状況での特定の最適化)を除いて適用されません。

これらの特別な場合でも、一般に、実際のテーブル行のデータ自体 (Blob などの実際のデータへのポインターを含む) は、1 つの IO ページに格納されなければなりません...。

例外です。 唯一の場所である Select * の後にあるサブクエリの中だけです。 Exists または Not Exists のような述語節があります。

   Select colA, colB
   From table1 t1
   Where Exists (Select * From Table2
                 Where column = t1.colA)

EDIT: @Mike Sherer のコメントに対して、はい、技術的にも、あなたの特別なケースのための少しの定義と、美的にも、それは真実です。まず、要求された列のセットがインデックスに格納されている列のサブセットである場合でも、クエリ プロセッサは すべての すべての I/O はページ単位で行われなければならず、インデックスデータはテーブルデータと同様に IO ページに保存されます。 したがって、インデックス ページに対して、インデックスに格納されている列のセットとして "tuple" を定義しても、このステートメントは真であることに変わりはありません。

というのは、I/Oページ内に格納されているものに基づいてデータをフェッチし、要求されたものには基づいておらず、ベーステーブルI/OページまたはインデックスI/Oページにアクセスしているかどうかにかかわらず、このステートメントは真であるからです。

を使用しない他の理由としては Select * を参照してください。 なぜ SELECT * は有害だと考えられているのでしょうか? :