ストレージエンジンはオプティマイザに使用されるテーブルの統計を集めます。テーブル統計は値グループに基づき、値グループは同じキープリフィックス値を持つ行のセットです。オプティマイザの目的に関しては、標準グループサイズは重要な統計となります。
MySQLは標準値グループサイズを以下のように使用します。
各ref
アクセスごとに読まれなければならない行の数を推測
一部 joinが生成する行の数を推測するため:つまり、このフォームのオペレーションが生成する行の数になります。
(...) JOINtbl_name
ONtbl_name
.key
=expr
インデックスの標準値グループサイズが増加する毎に、その2つの目的に関してはインデックスは役に立たなくなります。というのも、ルックアップあたりの標準行数は増加するためです。最適化の目的のためにインデックスが有用であるため、各インデックス値はターゲットとするテーブル内の行の数は少なくなければいけません。既存のインデックス値が大量の行を生成する際、インデックスは役に立たなくなり、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
システム変数を使用することで、テーブル統計コレクションが管理されます。この変数には2つの可能値があり、これらは以下のとおり異なります。
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
ルックアップに使用させることがあるかもしれません。
=
よりも<=>
を使用するjoinを多くユーザが使用している場合、NULL
値は比較では特別ではなく、1つのNULL
は他のものと等価です。この場合、nulls_equal
は適切な統計メソッドです。
myisam_stats_method
システム変数はグローバルとセッション値を保持しています。グローバル値の設定はMyISAM
テーブルに対するMyISAM
統計収集に影響を与えます。
セッション値を設定することで、現在のクライント接続のみに対する統計収集に影響が与えられます。これは、既存のメソッドで他のクライントに影響を与えず、テーブルの統計をセッション値myisam_stats_method
に設定することで再生することが可能です。
テーブル統計を再生するために、以下のメソッドを使用してください。
myisam_stats_method
を設定し、CHECK
TABLE
ステートメントを発行します。
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
メソッドに近いです。