1. ホーム
  2. sql

[解決済み】SELECT *が有害とされるのはなぜですか?

2022-04-15 21:15:05

質問

なぜ SELECT * 悪い習慣?欲しいカラムを新たに追加した場合、変更するコードが少なくなるのではないでしょうか?

というのはわかるのですが SELECT COUNT(*) しかし、本当にすべてのカラムが必要な場合はどうすればよいのでしょうか?

どうすればいい?

理由は大きく分けて3つあります。

  • コンシューマーへのデータ移動の非効率性。 SELECT *を使用する場合、アプリケーションが機能するために本当に必要な数よりも多くのカラムをデータベースから取得することがよくあります。 そのため、データベースサーバーからクライアントへのデータ移動が多くなり、アクセスが遅くなったり、マシンの負荷が増加したり、ネットワーク上を移動するのに時間がかかったりします。 これは、元の利用者がデータアクセスをコード化したときには存在せず、必要とされていなかった新しいカラムを、誰かが基礎となるテーブルに追加したときに特に当てはまります。

  • インデックスに関する問題。 クエリを高いパフォーマンスでチューニングしたいシナリオを考えてみましょう。 もし、*を使用し、実際に必要な数よりも多くのカラムを返した場合、サーバーはデータを取得するために、他の方法よりも高価な方法を実行しなければならないことがよくあります。 たとえば、SELECT リストのカラムを単純にカバーするインデックスは作成できないでしょうし、作成できたとしても(すべてのカラム [ 震え声 その結果、最適化されたカバーインデックスがオプティマイザによって無視され、クエリのパフォーマンスが明白な理由もなく大幅に低下することになります。

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

しかし、SELECT *については、悪いことばかりではありません。 私はこのようなユースケースで惜しみなく使っています。

  • アドホッククエリ。 何かをデバッグしようとするとき、特に私がよく知らない狭いテーブルからデバッグしようとするとき、SELECT *はしばしば私の親友となります。 SELECT * を使えば、カラム名を調べることなく、何が起こっているのかを確認することができます。 これは、カラム名が長くなればなるほど、より大きな利点となります。

  • が行を意味する場合。 SELECT * がパフォーマンスを低下させるという噂は、何年も前には有効であったかもしれませんが、現在では有効ではありません。

    SELECT COUNT(*) FROM table;
    
    

    この場合、* は "count the rows" を意味します。 もし、*の代わりにカラム名を使うのであれば、, そのカラムの値が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を使ったりする人もいますが、IMOではこれらの慣例はかなり無意味です。 あなたが言いたいのは、"count the row"であり、それが*の意味するところなのです。 ほとんどのクエリオプティマイザは、このことを十分承知しています。 (正直なところ、私は 知る これはSQL ServerやOracleでも同じことが言えます)。