SQLの選択中、DBはSELECT a、b、cのSELECT *であるかどうかに関係なく、常にテーブルのメタデータを参照します。なぜですか?システム上のテーブルの構造とレイアウトに関する情報がそこにあるためです。
この情報を読まなければならない理由は2つあります。1つは、ステートメントをコンパイルするだけです。少なくとも既存のテーブルを指定することを確認する必要があります。また、最後に文が実行されてからデータベース構造が変更されている可能性があります。
さて、明らかに、DBメタデータはシステムにキャッシュされますが、実行する必要があるのはまだ処理中です。
次に、メタデータを使用してクエリプランが生成されます。これは、ステートメントがコンパイルされるたびにも発生します。繰り返しますが、これはキャッシュされたメタデータに対して実行されますが、常に実行されます。
この処理が行われないのは、DBが事前にコンパイルされたクエリを使用しているか、以前のクエリをキャッシュしている場合のみです。これは、リテラルSQLではなくバインディングパラメータを使用するための引数です。「SELECT * FROM TABLE WHERE key = 1」は「SELECT * FROM TABLE WHERE key =?」とは異なるクエリです。「1」はコールにバインドされています。
DBはそこでの作業をページキャッシングに大きく依存しています。最近のDBの多くは、メモリに完全に収まるほど小さい(または、おそらく、現代のメモリは、多くのDBに収まるほど大きい)です。次に、バックエンドでの主なI / Oコストは、ロギングとページフラッシュです。
ただし、DBのディスクを使用している場合、多くのシステムで行われる主な最適化は、テーブル自体ではなく、インデックス内のデータに依存することです。
あなたが持っている場合:
CREATE TABLE customer (
id INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(150) NOT NULL,
city VARCHAR(30),
state VARCHAR(30),
zip VARCHAR(10));
CREATE INDEX k1_customer ON customer(id, name);
次に、 "SELECT id、name FROM customer WHERE id = 1"を実行すると、DBがこのデータをテーブルからではなく、インデックスからプルする可能性が非常に高くなります。
どうして?とにかく、クエリを満たすためにインデックスを使用します(テーブルスキャンに対して)。また、where句で 'name'が使用されていなくても、そのインデックスはクエリにとって最良のオプションです。
これで、データベースにはクエリを満たすために必要なすべてのデータが揃ったので、テーブルページ自体をヒットする必要はありません。インデックスを使用すると、一般的にテーブルと比べてインデックスの行密度が高くなるため、ディスクトラフィックが減少します。
これは、一部のデータベースで使用されている特定の最適化手法についての波状の説明です。多くの場合、いくつかの最適化およびチューニング手法があります。
最後に、SELECT *は、手動で入力する必要がある動的クエリに役立ちます。「実際のコード」には使用しません。個々の列の識別により、クエリを最適化するために使用できるより多くの情報がDBに提供され、スキーマの変更などに対するコードの制御が向上します。
SELECT
クエリの実行/処理方法はデータベースごとに異なる可能性があります。