select * は禁じ手で、必ず列名を列挙すべしとされている理由


select * from ... と書いてはダメ、たとえ全列取得する場合でも select a, b, c, d from ... と書くのが常識、という話をずいぶん前に聞いたことがあって、意味がわからないので人力検索に投げてみた。
いただいた回答を整理しておく。

テーブル内の一部の列を参照したい場合

例えばクライアント側では1列しか見ないのにワイルドカードで全列取得することには、パフォーマンス上の問題がある。
select * from ... でも select a from ... でもディスクI/Oのコストは基本的に変わらないが*1、それ以外のところに問題がある。

  • ネットワークの問題。DBサーバからクライアントに転送するデータが無駄に大きくなる
  • メモリの問題。DBMSのデータキャッシュやOSのファイルキャッシュが無駄遣いされる

テーブルの全ての列を参照したい場合

全列取得したい場合は、select * と書いてもパフォーマンス上の問題はない。
紹介されたリンク先に「ワイルドカードを列名に展開するコストがかかるのでよくない」という意味のことが書いてあったが、それは1ms以下の世界の話で、人間には感知できないだろう。
ていうか「メタデータを参照して、* を a, b, c, d に変換する」コストを問題視するなら「メタデータを参照して、select a, b, c, d from ... に列挙された列名が正しいかチェックする」コストも問題じゃないのか。ワイルドカードを指定すればそのコストを避けられるから速い、て言ってもよくなるんじゃないか。

保守性の問題

あと、列名を明示することでメンテしやすくなるという指摘があった。

  • テーブルにカラムを追加削除したら、select * で取れる結果表の形が知らないうちに変わってしまう。取れたレコードに添字でアクセスしたら違う列の値が取れてしまう
  • 「テーブルの定義が変わった場合、ストアドなど再コンパイラしないと エラーになる場合があります」 <-- これは知らなかった。ありがたい

他にも理由があれば教えてください。
http://q.hatena.ne.jp/1231235330

*1:インデックスのある列のみselect/whereで参照する場合は別。データページを見ないからワイルドカードよりもI/Oが少なくなる、かもしれない