SELECT * が有害だと考えられるのはなぜですか? 質問する

SELECT * が有害だと考えられるのはなぜですか? 質問する

なぜSELECT *悪い習慣なのでしょうか? 必要な新しい列を追加すれば、変更するコードが少なくなるのではないですか?

SELECT COUNT(*)一部の DB ではパフォーマンスの問題になることは理解していますが、すべての列が本当に必要な場合はどうなるでしょうか?

ベストアンサー1

実際には、3 つの主な理由があります。

  • 消費者へのデータの移動が非効率です。SELECT * を実行すると、多くの場合、アプリケーションが実際に機能するために必要な数よりも多くの列がデータベースから取得されます。これにより、データベース サーバーからクライアントに移動するデータが増え、アクセスが遅くなり、マシンの負荷が増加するだけでなく、ネットワークを移動する時間も長くなります。これは、元の消費者がデータ アクセスをコーディングしたときには存在せず、必要でなかった新しい列を誰かが基礎となるテーブルに追加した場合に特に当てはまります。

  • インデックス作成の問題。クエリをチューニングして、高いパフォーマンス レベルにしたいシナリオを考えてみましょう。* を使用して、実際に必要な列よりも多くの列が返された場合、サーバーは、通常よりもコストの高い方法でデータを取得する必要があります。たとえば、SELECT リスト内の列だけをカバーするインデックスを作成することはできません。また、たとえそうしたとしても (すべての列を含む [ぞっとする])、次に誰かがやって来て、基になるテーブルに列を追加すると、最適化されたカバー インデックスがオプティマイザーによって無視され、クエリのパフォーマンスがすぐにはわからないまま大幅に低下することになります。

  • バインディングの問題。SELECT * を実行すると、2 つの異なるテーブルから同じ名前の 2 つの列を取得することができます。これにより、データ コンシューマーがクラッシュすることがよくあります。2 つのテーブルを結合するクエリを想像してください。両方のテーブルに "ID" という列が含まれています。コンシューマーは、どちらがどちらであるかをどうやって知るのでしょうか。SELECT * は、基になるテーブル構造が変更されると、ビューを混乱させることもあります (少なくとも一部のバージョンの SQL Server では)。ビューは再構築されず、返されるデータは意味不明になる可能性があるそして、最悪なのは、列に好きな名前を付けることができても、次に来る人は、既に作成した名前と衝突する列を追加することを心配しなければならないことを知るすべがないかもしれないということです。

しかし、SELECT * にとってすべてが悪いわけではありません。私は以下のユースケースでこれを頻繁に使用しています。

  • アドホック クエリ。何かをデバッグしようとするとき、特にあまり詳しくない狭いテーブルからデバッグしようとするとき、SELECT * は私の最高の味方です。基礎となる列名が何であるかを大量に調べなくても、何が起こっているかを簡単に把握できます。列名が長くなるほど、これは大きな「プラス」になります。

  • * が「行」を意味する場合。次の使用例では、SELECT * は問題なく、パフォーマンスを低下させるという噂は単なる都市伝説であり、何年も前にはある程度の妥当性があったかもしれませんが、現在はそうではありません。

    SELECT COUNT(*) FROM table;
    

    この場合、 * は「行を数える」ことを意味します。 * の代わりに列名を使用すると、その列の値が null でない行が数えられます。 COUNT(*) は、を数えるという概念を本当に理解させ、集計から NULL が排除されることによって引き起こされる奇妙なエッジケースを回避します。

    次のタイプのクエリでも同様です:

    SELECT a.ID FROM TableA a
    WHERE EXISTS (
        SELECT *
        FROM TableB b
        WHERE b.ID = a.B_ID);
    

    価値のあるデータベースでは、* は単に「行」を意味します。サブクエリに何を入れるかは関係ありません。SELECT リストで b の ID を使用したり、数字の 1 を使用したりしている人もいますが、私の意見では、これらの規則はほとんど意味がありません。あなたが言いたいのは「行を数える」ことであり、それが * が意味するものです。ほとんどのクエリ オプティマイザーはこれを理解できるほど賢いです。(正直に言うと、これが正しいと私が知っているのは SQL Server と Oracle だけです。)

おすすめ記事