MySQL 8.0 リファレンスマニュアル


8.2.1.23 全テーブルスキャンの回避

MySQL がフルテーブルスキャンを使用してクエリーを解決する場合、EXPLAIN からの出力には type カラムに ALL と示されます。 これは通常は次の条件で発生します。

  • テーブルがきわめて小さいため、キールックアップで煩わされるよりもテーブルスキャンを実行する方が速くなります。 これは、10 行未満の行や短い行長のテーブルによくあります。

  • インデックスが設定されたカラムに対して、ON または WHERE 句に使用可能な制限がありません。

  • インデックスが設定されたカラムと定数値を比較していて、MySQL が (インデックスツリーに基づいて) その定数がテーブルのきわめて大きい部分をカバーしており、テーブルスキャンが高速に行われると計算しました。 セクション8.2.1.1「WHERE 句の最適化」を参照してください。

  • 別のカラム経由で、カーディナリティーが低い (多数の行がキー値に一致する) キーを使用しています。 この場合、MySQL では、キーを使用することで多くのキー検索が必要になり、テーブルスキャンが高速になると想定しています。

小さいテーブルでは、テーブルスキャンは多くの場合に適切であり、実行の影響は無視できます。 大きいテーブルでは、オプティマイザがテーブルスキャンを誤って選択しないように、次の技法を試してください。

  • ANALYZE TABLE tbl_name を使用して、スキャンされるテーブルのキー分布を更新します。 セクション13.7.3.1「ANALYZE TABLE ステートメント」を参照してください。

  • スキャンされるテーブルに FORCE INDEX を使用して、MySQL に、テーブルスキャンは指定したインデックスを使用するのと比較して著しく負荷が大きいことを伝えます。

    SELECT * FROM t1, t2 FORCE INDEX (index_for_column)
      WHERE t1.col_name=t2.col_name;

    セクション8.9.4「インデックスヒント」を参照してください。

  • --max-seeks-for-key=1000 オプションを使用して mysqld を開始するか、または SET max_seeks_for_key=1000 を使用して、オプティマイザに、キースキャンでは 1,000 より多くのキーシークは発生しないと想定するように伝えます。 セクション5.1.8「サーバーシステム変数」を参照してください。


関連キーワード:  テーブル, インデックス, InnoDB, スキャン, ステートメント, キー, 結合, クエリー, カラム, 状態