InnoDB
テーブルに対する ANALYZE TABLE
の複雑さは、次のものに依存します。
innodb_stats_persistent_sample_pages
で定義される、サンプリングされるページの数。テーブル内のインデックス付きカラムの数
パーティションの数。 テーブルにパーティションが存在しない場合、パーティションの数は 1 であるとみなされます。
これらのパラメータを使用すると、ANALYZE TABLE
の複雑さを推定するための概略の計算式は次のようになります。
innodb_stats_persistent_sample_pages
の値 * テーブル内のインデックス付きカラムの数 * パーティションの数
通常は、この結果の値が大きいほど、ANALYZE TABLE
の実行時間も大きくなります。
innodb_stats_persistent_sample_pages
は、グローバルレベルでサンプリングされるページの数を定義します。 個々のテーブルのサンプリングされるページの数を設定するには、CREATE TABLE
または ALTER TABLE
で STATS_SAMPLE_PAGES
オプションを使用します。 詳細は、セクション15.8.10.1「永続的オプティマイザ統計のパラメータの構成」を参照してください。
innodb_stats_persistent=OFF
である場合、サンプリングされるページの数は innodb_stats_transient_sample_pages
で定義されます。 詳細は、セクション15.8.10.2「非永続的オプティマイザ統計のパラメータの構成」を参照してください。
ANALYZE TABLE
の複雑さを推定するためのより詳細なアプローチを示すために、次の例を考えてみます。
ビッグオー表記では、ANALYZE TABLE
の複雑さは次のように記述されます。
O(n_sample
* (n_cols_in_uniq_i
+ n_cols_in_non_uniq_i
+ n_cols_in_pk * (1 + n_non_uniq_i))
* n_part)
ここでは:
n_sample
は、サンプリングされるページの数 (innodb_stats_persistent_sample_pages
で定義されます)n_cols_in_uniq_i
は、すべての一意のインデックス内のすべてのカラムの総数 (主キーカラムはカウントしない)n_cols_in_non_uniq_i
は、すべての非一意インデックスのすべてのカラムの合計数ですn_cols_in_pk
は、主キー内のカラム数 (主キーが定義されていない場合、InnoDB
は単一カラムの主キーを内部的に作成します)n_non_uniq_i
は、テーブル内の一意でないインデックスの数ですn_part
は、パーティションの数。 パーティションが定義されていない場合、そのテーブルは単一パーティションであるとみなされます。
ここで、主キー (2 つのカラム)、一意インデックス (2 つのカラム) および 2 つの非一意インデックス (それぞれ 2 つのカラム) を持つ次のテーブル (テーブル t
) について考えてみます:
CREATE TABLE t (
a INT,
b INT,
c INT,
d INT,
e INT,
f INT,
g INT,
h INT,
PRIMARY KEY (a, b),
UNIQUE KEY i1uniq (c, d),
KEY i2nonuniq (e, f),
KEY i3nonuniq (g, h)
);
上で説明したアルゴリズムに必要なカラムとインデックスデータについて、テーブル t
の mysql.innodb_index_stats
永続的インデックス統計テーブルにクエリーします。 n_diff_pfx%
の統計には、各インデックスに対してカウントされるカラムが示されます。 たとえば、カラム a
および b
は、主キーのインデックスに対してカウントされます。 一意でないインデックスの場合、主キーカラム (a,b) は、ユーザー定義カラムに加えてカウントされます。
InnoDB
永続的統計テーブルの詳細は、セクション15.8.10.1「永続的オプティマイザ統計のパラメータの構成」を参照してください。
mysql> SELECT index_name, stat_name, stat_description
FROM mysql.innodb_index_stats WHERE
database_name='test' AND
table_name='t' AND
stat_name like 'n_diff_pfx%';
+------------+--------------+------------------+
| index_name | stat_name | stat_description |
+------------+--------------+------------------+
| PRIMARY | n_diff_pfx01 | a |
| PRIMARY | n_diff_pfx02 | a,b |
| i1uniq | n_diff_pfx01 | c |
| i1uniq | n_diff_pfx02 | c,d |
| i2nonuniq | n_diff_pfx01 | e |
| i2nonuniq | n_diff_pfx02 | e,f |
| i2nonuniq | n_diff_pfx03 | e,f,a |
| i2nonuniq | n_diff_pfx04 | e,f,a,b |
| i3nonuniq | n_diff_pfx01 | g |
| i3nonuniq | n_diff_pfx02 | g,h |
| i3nonuniq | n_diff_pfx03 | g,h,a |
| i3nonuniq | n_diff_pfx04 | g,h,a,b |
+------------+--------------+------------------+
上に示したインデックス統計データとテーブル定義に基づいて、次の値を確認できます。
n_cols_in_uniq_i
(すべての一意のインデックス内のすべてのカラムの総数、主キーカラムはカウントしない) は 2 (c
およびd
)n_cols_in_non_uniq_i
、一意でないすべてのインデックスのすべてのカラムの合計数は 4 (e
,f
,g
およびh
) ですn_cols_in_pk
(主キー内のカラム数) は 2 (a
およびb
)テーブル内の一意でないインデックスの数である
n_non_uniq_i
は 2 (i2nonuniq
およびi3nonuniq
) ですn_part
(パーティションの数) は 1。
これで、スキャンされるリーフページの数を決定するために innodb_stats_persistent_sample_pages
* (2 + 4 + 2 * (1 + 2)) * 1 を計算できます。 innodb_stats_persistent_sample_pages
が 20
のデフォルト値に設定されており、かつページサイズがデフォルトの 16 KiB
(innodb_page_size
=16384) である場合は、テーブル t
に対して 20 * 12 * 16384 バイト
、つまり約 4 MiB
が読み取られると推定できます。
一部のリーフページはすでにバッファープール内にキャッシュされている可能性があるため、4 MiB
のすべてがディスクから読み取られるとは限りません。