保留統計の索引統計0件問題について [アーキテクチャ]

今までかかわっていたプロジェクトが一段落して離れることとなり少し落ち着いた時間が取れたので、先日コミュニティに投稿した、保留統計でgather_table_statsで索引の統計情報を取得すると、索引の統計がnum_rows=0となってしまうことがある、という事象について、ここで紹介しておきたい。

gather_table_stats doesn't gather related index stats properly when pending stats are enabled

事象の詳細や再現方法については上記を見て頂きたいが、簡単に言えば、保留統計を使っている表に対してgather_table_statsで表と一緒に索引の統計情報を取得するとき(カスケードオプション有効)、ある条件を満たすと索引の統計が適切に取得できない、より具体的には表の件数が有件なのに、索引の統計(num_rows)が0になってしまうのである。これが発生するのは表の(パブリッシュされた)統計(num_rows)が0で、保留統計を使っており、gather_table_statsでカスケードオプション有効にした場合に発生する。上記投稿で示したテストケースは19.3である。

この事象は新規不具合のため修正されるまではしばらく時間がかかる(一般的には21cまたは22cに取り込まれ、旧バージョンへバックポートされる流れになる)と思われる。このため、この事象を回避するワークアラウンドの確立が課題である。上記投稿ではパブリッシュ前にそのような問題を含んでいる可能性のある索引を抽出する方法について記載したが、実運用上この問題の影響と対処方法について少し補足しておきたい。

まず統計情報取得するシーンとして大きく2つあると考えている。1つは自動統計情報収集、これはOracleの一般的な統計情報取得方法であり、メンテナンスウィンドウに設定された時間帯に統計情報が古くなった表を選定(デフォルトでは更新が10%以上)し、統計情報を取得するケースである。システムが運用されている状態では、この方法で統計情報を取得していることがほとんどであろう。この問題の特性から有件の表に対しては統計情報取得に問題がないことは明らかであろう。あるとすれば、有件→0件→有件を繰り返すケースであろうが、そもそもそのようなテンポラリ表のような使い方のテーブルであれば、統計情報の状態を自動統計に任せること自体問題となる可能性があるので、統計ロックすることを検討するだろう。

もう一つのシーンは手動での統計情報収集である。これは、運用開始前のデータ移行や、リリースに伴う新規表の作成の際に、統計情報を適切な状態にするためにDBAが手動で統計情報を取得するケースである。この統計情報をどのような状態にすべきかは状況によって異なるだろうが、概ね初期データ投入後の状態で取得するか、あるいは空の状態としておき、何等かの契機でデータが投入された後を狙って手動で取得するといったケースが考えられる。いずれのケースにおいても、保留統計を使う場合は注意が必要である。空の状態で統計情報取得・パブリッシュして0件統計の状態を作ってしまうと、有件になったときの統計情報取得でこの事象の影響で意図せず索引統計が0となり、実行計画が適切でなくなるリスクがある。回避するには、0件統計をとらない、つまり0件の場合はあえてNULL統計にしておく、そして有件になった適切なタイミングで統計情報を取得することが一番簡易な対処である。ただ、0件の状態で統計情報を取得するなら、その後の統計情報取得では、必ず索引の統計情報が適切に取得できているかをパブリッシュ前に確認し、必要であれば、索引統計を再取得する、という運用を徹底することである。

索引のnum_rowsが0となってしまう弊害は、主に実行計画が適切でないことに伴う性能遅延に尽きる。ある表に複数の索引がある場合に、索引のnum_rowsが0であった場合、問い合わせのプレディケートに合致する索引が複数あった場合にコストが適切に算出できず、適切な索引が選択されない可能性がある。実際に、このような事象に遭遇した経験から、統計情報を手動取得する場合は、上記投稿にあるチェックSQLを実行し、索引統計に問題ないことを確認する運用を、少なくとも製品不具合が解消されるまでは徹底することが必要だと考える。手間としてはわずかであるが、このひと手間で後続の性能遅延のリスクを低減できるなら、これは十分実施検討するに値すると考える。

なお、コミュニティのSureshさんからは古い19cでは不具合多いよね、とのコメントを頂いたが、21cでも再現することが確認できたと聞いているので、おそらくこの事象は最新の19cでも修正されていないはずである。私の手元のテスト環境をそろそろ最新にバージョンアップさせなければと思う今日この頃である。Jonathan Lewisさんからの「いいね」が心の支えになっていることは言うまでもない。

以上