ストレージエンジンはオプティマイザに使用されるテーブルの統計を集めます。テーブル統計は値グループに基づき、値グループは同じキー接頭辞値を持つ行のセットです。オプティマイザの目的に関しては、標準グループサイズは重要な統計となります。
MySQL は標準値グループサイズを次のように使用します。
各 ref
アクセスごとに読まれなければならない行の数を推測一部
join
が生成する行の数を推測するため:つまり、このフォームのオペレーションが生成する行の数になります。
インデックスの標準値グループサイズが増加する毎に、その 2 つの目的に関してはインデックスは役に立たなくなります。
(...) JOINtbl_name
ONtbl_name
.key
=expr
というのも、ルックアップあたりの標準行数は増加するためです。最適化の目的のためにインデックスが有用であるため、各インデックス値はターゲットとするテーブル内の行の数は少なくなければいけません。既存のインデックス値が大量の行を生成する際、インデックスは役に立たなくなり、MySQL はそれを使用しなくなります。
標準値グループサイズはテーブルカーディナリティと関連しています。これは値グループの数を指します。SHOW
INDEX
ステートメントは
N
/S
に基づくカーディナリティ値を表示します。これは
N
がテーブル内の行数であり、S
が標準値グループサイズとなります。その比率はテーブル内の値グループの概数を生成します。
<=>
比較演算子に基づく join
に対して、NULL
はほかの値と同様に扱われます。NULL
<=>
NULL
、ちょうど
がほかの
N
<=> N
N
であるように。
ただし、=
演算子に基づく
join に対して、NULL
は非 NULL
値と異なります。
は
expr1
= expr2
expr1
あるいは
expr2
(または両方) が
NULL
である場合、適切ではありません。このことは、フォーム
の比較に対する
tbl_name.key
= expr
ref
アクセスに影響を与えます。expr
の現在値が NULL
の場合、MySQL はテーブルにアクセスしません。
というのも、比較は適切でないからです。=
比較に対して、NULL
値の数がテーブル上にいくらであっても、関係ありません。最適化のためには、関連する値は非
NULL
値グループの標準サイズにします。ただし、現在
MySQL
は標準サイズを収集または使用することを許可しません。
MyISAM
テーブルに対して、myisam_stats_method
システム変数を使用することで、テーブル統計コレクションが管理されます。この変数には
3
つの可能値があり、これらは次のように異なります。
myisam_stats_method
が nulls_equal
の場合、すべての
NULL
値は等価として扱われます。つまり、それらはすべてシングル値グループを形成します。
NULL
値グループサイズは標準非
NULL
値グループサイズよりはるかに大きくなります。このメソッドは標準値グループサイズを大きくゆがませます。これによりオプティマイザから見たインデックスは非
NULL
値を検索する
join
に対して役に立たないように見えます。結果的に、nulls_equal
メソッドはオプティマイザに
ref
アクセスに対してインデックスを使用すべきときでも使用しないままにする可能性があります。
myisam_stats_method
が nulls_unequal
のとき、NULL
値は等価として扱われません。代わりに、各
NULL
値はサイズ 1
の別値グループを生成します。
NULL
値が多い場合、このメソッドは標準値グループサイズを小さくゆがませます。もし標準非
NULL
値グループサイズが大きい場合、NULL
値をサイズ 1
のグループとして取り扱うと、オプティマイザに非
NULL
値を探させる
join
のインデックス値を過大評価します。結果的に、nulls_unequal
メソッドは、ほかのメソッドの方が適しているにもかかわらず、オプティマイザにこのインデックスを
ref
ルックアップに使用させることがあるかもしれません。
myisam_stats_method
が nulls_ignored
の場合、NULL
値は無視されます。
=
よりも<=>
を使用する
join
を多くユーザーが使用している場合、NULL
値は比較では特別ではなく、1 つの
NULL
はほかのものと等価です。この場合、nulls_equal
は適切な統計メソッドです。
myisam_stats_method
システム変数はグローバルとセッション値を保持しています。グローバル値の設定は
MyISAM
テーブルに対する
MyISAM
統計収集に影響を与えます。セッション値を設定することで、現在のクライアント接続のみに対する統計収集に影響が与えられます。これは、既存のメソッドでほかのクライアントに影響を与えず、テーブルの統計をセッション値
myisam_stats_method
に設定することで再生することが可能です。
テーブル統計を再生するために、次のメソッドを使用してください。
myisamchk
--stats_method=method_name
--analyze を実行します。
テーブルを変更し統計を旧値とし
(たとえば、行を挿入し、それから削除します)、そして
myisam_stats_method
を設定し ANALYZE
TABLE
ステートメントを発行します。
myisam_stats_method
の使用に関する警告。
次で説明されているように、強制的にテーブル統計を明示的に収集させることができます。ただし、MySQL
も自動的に統計を収集する可能性があります。たとえば、テーブルステートメント実行時、ステートメントの中にはテーブルを改良するものもあり、MySQL
は統計を収集する可能性があります。(たとえば、これは大量挿入や削除時、または
ALTER TABLE
ステートメントの際に起こる可能性があります)。これが生じた場合、統計は
myisam_stats_method
がそのときどきで持っている値を使用して統計が収集されます。よって、あるメソッドで統計を収集したが
myisam_stats_method
が自動的にテーブル統計が収集された後他のメソッドに設定されている場合、ほかのメソッドが使用されます。
既存の MyISAM
テーブルに対してどのメソッドが統計生成に使用されたかを知ることはできません。
myisam_stats_method
は MyISAM
テーブルにのみ適用されます。ほかのストレージエンジンはテーブル統計を収集するメソッドが
1
つしかありません。通常は、nulls_equal
メソッドに近いです。