その4>ペンネーム:クリープ前回、前々回と、MLOGについて検証しました。今回は、高速リフレッシュについてです。この機能を使ったことがある人であれば、必ず疑問に思うであろう制限のしくみについて見てみましょう。■■■■■今回のあらすじ■■■■■1)高速リフレッシュ制限について2)制限:COUNT(*)が、SELECT句に必要。Production1)高速リフレッシュの制限について高速リフレッシュを使用されている方ならご存知と思いますが、この機能を利用するにはいくつかの制限があります。中でも、通常の集計SQL文では間違いなく無いと思われる制限が以下ではないでしょうか。COUNT(*)が、SELECT句に必要。集計関数が使用されているマテビューの場合マテビューの機能を使ったことがない、又は高速リフレッシュを使ってない人にしてみれば、「なんで必要なの?」と思うのでは???高速リフレッシュの機能を使用してても、この制限の意味はわからずに、おまじないのようにSELECT句に追加している人も多いのではないでしょうか。いうことで、ここからはこの疑問を解消すべく、検証を行って行きたいと思います。2)制限:COUNT(*)が、SELECT句に必要。それでは早速、COUNTの制限について確認していきましょう。マテビューで使用できる集計関数は以下の通り。MAXこれらの関数を使用した場合、COUNT(*)をつけないと高速リフレッシュすることができません。dbms_mview.refresh('mv_parttime');PL/SQLプロシージャが正常に完了しました。???できちゃいました。上記のようなマテビューでも問題なく高速リフレッシュすることができるようです。して、マニュアル間違えてる???確認確認。すべてのタイプの高速リフレッシュを保証するには、常にCOUNT(*)が必要です。ないと、挿入後の高速リフレッシュのみに制限される場合があります。「挿入後の高速リフレッシュ」のみ、つまりInsert文のみ可能ということのようです。なんだか、不思議な制限。dbms_mview.refresh('mv_parttime');行1でエラーが発生しました。"SCOTT"."MV_PARTTIME"のREFRESHFASTは削除/更新の後ではサポートされていません。行1マニュアル通り!?UPDATE文ではエラーになりました。削除/更新とあるので、きっと、DELETE文も同様なのでしょう。通常の動きを確認したところで、count(*)を追加したマテビューを作成。dbms_mview.refresh('mv_parttime');PL/SQLプロシージャが正常に完了しました。count(*)を追加することで、先ほど失敗したUPDATE文も問題なく処理することができました。これはつまり、高速リフレッシュで集計する場合、count(*)はなくてはならない、いわば「コーヒーにクリープ」な存在と言えるでしょう!?しかし、何故、count(*)が必要なのでしょうか。STMT見てみると、マテビューに怪しげなDELETE文が実行されていました。“CNT_ALL”=0。!COUNT(*)は、COUNT(*)の結果が0の項目をマテビューから削除する為に必要ってことか。集計されたマテビューは、前回の検証で見てきたようにMLOGの差分で計算しています。1現在のマテビューは上記のように、先ほどINSERTした1件のみがあります。ここでDELETE文を実行した場合、MLOGは以下のようになります。0000この後に高速リフレッシュした場合、前回の検証の通り、マテビューのSALの値とMLOGの値の差分を計算し、SUM_SALの値を0に更新します。差分の計算だけだと、以下のようなデータになってしまいます。0このままでは、元表とは異なったものになってしまいます。0)で、上記の行を削除している、という訳。ちなみに、UPDATE文は?とお思いの方。UPDATE文の場合も残り続けてしまうことがあります。元表ではPART-TIMEのデータはなくなり、DELETEと同じことになります。※わからない方は、実際に試してみましょう。冒頭にあったINSERTのみ保証されるという不思議な制限も、このことを理解すれば納得することができるでしょう。ところで、先ほど作成したマテビューですが、count(*)といっしょにcount(sal)という項目が追加されていたのにお気づきでしょうか。job;これは集計関数が使用されているマテビューの要件として、count(sal)という項目が必要な為に追加しています。count(sal)という項目が必要なのでしょうか。reserved.トップページ企業概要プライバシーポリシ。