SQL は実際にどのように実行されますか?
たとえば、 で行を検索したい場合、row_id=123
SQL クエリはメモリの先頭から行ごとに検索しますか?
SQL は実際にどのように実行されますか?
たとえば、 で行を検索したい場合、row_id=123
SQL クエリはメモリの先頭から行ごとに検索しますか?
これは、クエリの最適化に関するトピックです。簡単に言えば、データベース システムは、クエリに基づいて、最初に最適なパフォーマンスが得られる可能性のあるクエリ プランを生成して最適化しようとし、次にそのプランを実行します。
のような選択の場合row_id = 123
、実際のクエリ プランは、インデックスがあるかどうかによって異なります。そうしないと、テーブル スキャンを使用してテーブルを行ごとに調べます。ただし、 にインデックスがある場合は、インデックスrow_id
を使用してほとんどの行をスキップする可能性があります。この場合、DB は行ごとに検索しません。
PostgreSQL または MySQL を実行している場合は、次を使用できます。
EXPLAIN SELECT * FROM table WHERE row_id = 123;
システムによって生成されたクエリ プランを表示します。
テーブルの例として、
CREATE TABLE test(row_id INT); -- without index
COPY test FROM '/home/user/test.csv'; -- 40,000 rows
EXPLAIN SELECT * FROM test WHERE row_id = 123
出力:
QUERY PLAN
------------------------------------------------------
Seq Scan on test (cost=0.00..677.00 rows=5 width=4)
Filter: (row_id = 123)
(2 rows)
これは、データベースがテーブル全体に対してシーケンシャル スキャンを実行し、行を検索することを意味しますrow_id = 123
。
ただし、列にインデックスを作成すると、次のようになりますrow_id = 123
。
CREATE INDEX test_idx ON test(row_id);
次に、EXPLAIN
データベースがインデックス スキャンを使用して、テーブル全体の処理を回避することを示します。
QUERY PLAN
--------------------------------------------------------------------------
Index Only Scan using test_idx on test (cost=0.00..8.34 rows=5 width=4)
Index Cond: (row_id = 123)
(2 rows)
EXPLAIN ANALYZE
を使用して、SQL クエリの実際のパフォーマンスを確認することもできます。私のマシンでは、シーケンシャル スキャンとインデックス スキャンの合計実行時間は、それぞれ14.738 msと0.171 msです。
クエリの最適化の詳細については、『Database Systems: The Complete Book 』の第 15 章と第 16 章を参照してください。