全表スキャン
全表スキャン (英: full table scan)、または順次スキャン (英: sequential scan)は、データベースで行われるテーブルの読み取り方法であり、テーブルの各行が順次(シリアル)順序で読み取られ、検出された列の条件が必要とされているものかどうかをチェックする[1]。 全表スキャン[2]は通常、複数のシークとディスクからメモリへの転送など、大量の読み取り操作が必要であり、通常とても遅い操作となる。
概要
[編集]データベースでは、インデックスが作成されていないクエリは全表スキャンになり、データベースはテーブルの各レコードを処理して、指定された要件を満たすすべてのレコードを検索する。クエリがテーブルからほんの数行を選択した場合でも、テーブル全体のすべての行が調べられる。この操作は通常、とても時間がかかるが、テーブルが非常に小さい場合や、インデックスを最新の状態に保つオーバーヘッドが高い場合は許容できる場合がある。
オプティマイザが全表スキャンを行う場合
[編集]全表スキャンを選択する上で最も重要な要素は速度である。これは、全表スキャンが最速であり、別のアクセス手法がない場合に使用することを意味する。全表スキャンを使う場合の例は次の通り[3]。
- インデックスがない場合
インデックスが存在しないため、オプティマイザは全表スキャンを使用する。
- 行数が少ない場合
テーブルが小さいため、全表スキャンのコストがインデックス範囲スキャンよりも低くなるとオプティマイザが見積もることがある。
- インデックスがある状態で、クエリがSELECT COUNT(*)を処理して、インデックスされた列にNULLが存在する場合
この場合、オプティマイザはインデックスを利用して行数を数えられない。これはインデックスがNULLの項目を含められないため。
- クエリによる結果がテーブルのほぼすべての行を取得する場合
戻り行の数が多すぎて、ほぼ100%のテーブル内容を取得する場合。この場合、クエリは「非選択的 (unselective)」であるという。
- テーブル統計が更新されていない場合
テーブルの行数が当初小さかったものが直近で急激に大きくなり、テーブルの統計がまだ更新されていないとする。この場合、オプティマイザーは、コストを正しく見積もることができず、全表スキャンを選択してしまうことがある。
- テーブルが高度な並列処理を備えている場合
高度な並列処理テーブルの場合、その程度によりオプティマイザーは全表スキャンを使用する選択をする場合がある。
- クエリに全表スキャンヒントが指定されている場合
全表スキャンを使うようヒントが指定されていると、オプティマイザは全表スキャンを強制的に使用する。
例
[編集]最初の例は、fruitsテーブル内の色が赤のすべての果物の名前を返すSQLステートメントを示している。fruitsテーブルに色列のインデックスがない場合、データベースエンジンは、各行の色を「赤」と比較するために、fruits内のすべての行をロードして調べる必要がある。
SELECT name FROM fruits WHERE color = 'red';
2番目の例は、fruitsテーブル内のすべてのfruitの名前を返すSQLステートメントを示している。このステートメントには抽出条件がないため(WHERE句なし)、すべての行のデータを取得することになる。そのため、データベースエンジンは、fruitsテーブルの名前列にインデックスがある場合でも、全表スキャンを使用してこのクエリのデータを取得する。この場合は、インデックスによる抽象化レイヤーを介してテーブルにアクセスするよりも高速になる。
SELECT name FROM fruits
3番目の例は、SQLエンジンが全表スキャンの代わりにほぼ確実にインデックスを使用する選択をする反例である。この例では、前のクエリとほぼ同じクエリを使用しているが、返される名前がアルファベット順になるようにORDER BY句を追加している。fruitsテーブルの名前列にインデックスがあるとすると、データベースエンジンはそのインデックスを使用して名前を順番に返す。これは、インデックスの追加の抽象化レイヤーを介してテーブルにアクセスすると、要求された順序で行を返すという利点があるためである 。エンジンが全表スキャンを使用して行をロードした場合、返された行を並べ替える追加の作業を実行する必要がある。極端な場合(データベースエンジンによって維持される統計がテーブルに含まれる行数が非常に少ないことを示している場合など)、オプティマイザはこのタイプのクエリに全表スキャンを使用する場合がある。
SELECT name FROM fruits ORDER BY name
長所と短所
[編集]長所:
- 読み取り時間のコストは予測可能。データベースは毎回テーブルのすべての行をスキャンするため。
- テーブルがデータベースブロックバッファの2%未満の場合、全表スキャンの方が高速となる。
短所:
- 全表スキャンは、インデックスがないか、SQLでインデックスが使用されていない場合に発生する。また、全表スキャンの結果は通常、インデックステーブルのスキャンよりも遅くなる。テーブルが大きいほど、データが返ってくるまでの時間が遅くなる。
- 不必要な全表スキャンは、データベース全体のプロセス負担を伴う大量の不必要なI/Oにつながる。
関連項目
[編集]脚注
[編集]- ^ “Avoiding Table Scans”. Oracle (2011年). 2021年3月23日閲覧。
- ^ “Which is Faster: Index Access or Table Scan?”. Microsoft TechNet (2002年). 2021年3月23日閲覧。
- ^ “Optimizer Access Paths”. Oracle. Oracle (2013年). 2021年3月23日閲覧。