免責事項
この翻訳は MySQL Server Blogの2014/12/15に公開された記事をユーザーが翻訳したものであり、Oracle公式の翻訳ではありません。
InnoDBのインデックス統計情報について
- MySQL 5.6には永続化された統計情報が導入された。これはInnoDBによって作成され、オプティマイザーによるクエリーの最適化に利用される。
- いくつかのやり方で、永続化された統計情報は更に性能を出せるはずだ。それについてあなたの意見を聞きたいと思う。
いくつのサンプルを取るか? という問題
- ほぼランダムにいくつかのページを選び出し、解析し、その結果を推測することで統計情報は作成される。
いくつのページがサンプリングに使われるかはSTATS_SAMPLE_PAGES句によってテーブルごとに指定することができる。たとえば、
ALTER TABLE t STATS_SAMPLE_PAGES=500;
のように指定できる。- この方法を使うことで、大きなテーブルに対してはより正確な推測のためにより多くのページをサンプリングさせることができる。
- 多くのページをサンプリングさせることはより良い統計情報を作成し、オプティマイザーが最適な実行計画を選ぶチャンスを増やすことができる。
- ただ一つのデメリットは、統計情報の作成そのもの(サンプリング処理)が遅くなることだ。
テーブルごとにサンプリングするページ数を指定できるというのは柔軟だけど、テーブルサイズのパーセンテージでそれを指定できるというのはどうだろう。ページ数を指定するより良いだろうか?
- パーセンテージをグローバル変数で指定するやり方はユーザーのニーズやユースケースに合わないんじゃないかと思う。同じパーセンテージでも、小さなテーブルでは良い統計情報を取るのには足りないかもしれないし、巨大テーブルではサンプリングが遅くなりすぎるかもしれないからだ。
- テーブルごとにパーセンテージで指定するというのは、今の機能「テーブルが大きいか小さいかを判断して、テーブルごとに正しいサンプルページ数を決め打ってやる」というやつよりもうちょっと良いやり方かもしれない。
どう思う? これについて意見が欲しい。
サンプリングのページ数はテーブルサイズのパーセンテージで指定するようにした方がいい?
- Yes, パーセンテージがいい
- No, ページ数を指定するやり方で上手く動いてる
- 結果はこちら (訳注: 投票する, 結果を見るには元記事のページを参照してください)
どのくらいの頻度でサンプリングするか? という問題
現在は、「前回の統計情報更新からテーブルの10%が変更 (行の更新、削除、または追加)される」と、InnoDBが自動的に統計情報を再計算するようになっている(どうやって分析するかは前の段落にある通り。サンプリング対象のページがキャッシュされてなければディスクから読み出す)
MySQL 5.5とそれ以前は、この閾値が6.25%だった。これは統計情報が頻繁に更新されすぎて、しょっちゅう実行計画が変わるという問題があった。一般的に10%がいい値だってことがわかったけれど、この閾値を動的に変えたがってるヘビーユーザーもいる。どうだろう? この統計情報更新をトリガーする閾値は、グローバル変数がいい? それともテーブルごとがいい? 動的に変更できたら、それを増減させる? 教えてほしい。
- Yes, 小さくする。10%は大きすぎる。
- Yes, 大きくする。10%は小さすぎる。
- No, 今のやり方で上手くいってる。
結果はこちら (訳注: 投票する, 結果を見るには元記事のページを参照してください)
フィードバック待ってます! いつもMySQLを使ってくれてありがとう!