[解決済み】SELECT *が有害とされるのはなぜですか?
質問
なぜ
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でも同じことが言えます)。
関連
-
[解決済み] ORA-01821: ISO 8601 のローカルタイム付き日付のフォーマットが認識されないエラー
-
[解決済み] Oracle Trigger ORA-04098: トリガーが無効で、再バリデーションに失敗しました。
-
[解決済み] SQL ServerでSELECTからUPDATEする方法とは?
-
[解決済み] 各GROUP BYグループの最初の行を選択しますか?
-
[解決済み] SQLのSELECTでIF...THENを実行するにはどうすればよいですか?
-
[解決済み] ...値に挿入する ( SELECT ... FROM ... )
-
[解決済み] SELECT' 文の 'IF' - カラムの値に基づいて出力値を選択する
-
[解決済み] 別のテーブルに一致する項目がない行を選択するにはどうすればよいですか?
-
[解決済み】NOT IN句の中のNULL値
-
[解決済み] どちらが速いか/ベストか?SELECT * または SELECT column1, colum2, column3, etc.
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 "指定された集約関数を含まないクエリを実行しようとしました。"
-
[解決済み】2つの列を分割する方法は?
-
[解決済み] 3を挿入すると「ORA-01438: この列で許容される指定精度より大きい値」と表示される。
-
[解決済み] ''付近の構文が正しくない
-
[解決済み] 2つの列を分割するには?
-
[解決済み] Varchar は Sum 演算子では無効です。
-
[解決済み] Presto SQL ピボッティング(言葉は悪いですが)データ
-
[解決済み] Presto の JSON_EXTRACT で ' ' 文字を含むキーに問題がある。
-
[解決済み] PostgreSQL - json 型の等値演算子を識別できませんでした。
-
[解決済み] トリガーがコンパイルエラーで作成される