ビューの功
ビュー(View)がとても便利な道具であることは、全ての DB エンジニアの方に同意してもらえるでしょう。もしビューなしで開発せねばならないとしたら、非常に手間が増えるに違いありません。特に正規化した結果、テーブルが増えすぎて結合が多く発生する場合など、あらかじめビューで厄介な部分を吸収させておくと、クエリがすっきりして効率的な開発が行なえます。クエリがすっきりするということは、バグも減るということです。しかも非正規化と違ってデータ独立性を保持できる「クリーン」な技術のうえ、ビューに必要な操作のみを許可することでセキュリティ強化にも役立つなど、その利点は多大です。デイトはビューを「クエリの缶詰」と、うまい表現をしました。保存がきく上に、開ければ常に新鮮なデータを取り出せる、というわけです。
ビューの罪
しかし、一時的な使い捨てビューならばともかく、システムの中に組み込まれるビューの場合は、その使用に慎重を期す必要があります。なぜなら、ビューには一つの大きな欠点があるからです。それは、パフォーマンスの低下です。最近はビューの性能も向上して、可能な限り実表のインデックスを使用する工夫などが取り入れられ、昔ほど酷い速度低下とメモリ圧迫はなくなりました。恐らく皆さんも、ビューの使用にためらいを感じる人は少ないでしょう。しかしそれでもなお、注意を要するケースがあります。それは、ビュー定義で集約操作を行なっているときです。具体的には、次のような演算が含まれる場合です。
- 集約関数( SUM、AVG、COUNT、MAX、MIN )
- 集合演算子( UNION、INTERSECT、EXCEPT(MINUS) )
理由は直観的にも想像がつくでしょう。集約した結果を得るには、もとの実表に対して集約を行なわざるをえないからです(結局のところ、ビューが実データを保持していない、ただの「クエリ」だという点を忘れないでください)。ことに、物理メモリによるソートが発生すると格段に SQL が遅くなります。また似たような理由から、ビューからさらに別のビューを作った場合も、パフォーマンス低下を招く危険があります。多重ビューは大変危険です。
つまるところ、NULL やインデックスなど、データベースにおける他の便利な道具や概念と同様の厳しい格言がビューにも当てはまるのです。すなわち
適切な使用は薬だが濫用すると毒になる
どうやら DB エンジニアは、この格言を常に胸にしまっておく必要がありそうです。それがなかなかできないのですけれど。
銀の弾になるか? ―― マテリアライズド・ビューの登場
もしビューの使用が実際にパフォーマンス低下を招いた場合、どう対処すればよいのでしょう。皆さんの隣には、「このビューに投げた SQL、1時間たっても返ってこないんですけど …… 」と困惑顔のプログラマがため息をついています。彼(女)の悩みをどう解決してあげればよいでしょう?
最近の DBMS はこの苦境に対する解決策をいくつか用意しています。一つが、ビューにインデックスを張るという技術。SQL Sever が実装しています。もう一つが、マテリアライズド・ビューの技術。Oracle、DB2、PostgreSQL が実装しています。
マテリアライズド・ビューというのは、直訳すれば「実体化されたビュー」、つまり文字通り、実データを保持するビューのことです。これはもう、ビューというよりほとんどテーブルに近い存在です。実際、Oracle の Enterprise Manager でオブジェクトの一覧を表示すると、ビューではなくテーブルの欄に出てきます。デイトも、マテリアライズド・ビューは本当の意味でのビューではない、と述べていてます[1]。マテリアライズド・ビューのアイデア自体は、けっこう昔から実現している DBMS もあったのですが、本格的に実装され始めたのは最近です。私も 100万行/テーブル を超える規模の業務では重宝しています。これがパフォーマンス面で劇的な改善をもたらす理由は、以下の三つです。
- 実データを保持するので、ビュー定義のクエリが発行不要である。
- 主キーを張れる
- インデックスも張れる
ここまで読んで「素晴らしい、私も明日からマテリアライズド・ビューに乗り換えよう」と思った方 ―― それは早計です。さきの格言をもう一度思い出してください。
適切な使用は薬だが濫用すると毒になる
これは残念ながら、マテリアライズド・ビューにも当てはまります。実データを保持することで、次に挙げる欠点を抱え込むことになります。
- リフレッシュの管理が必要である
- 普通のテーブルと同様に表領域を消費する
まとめ
ほとんどの方が、NULL の危険性は承知しておられるでしょう(と期待します)。しかしビューの危険性というのは、意外に盲点で、汚いテーブル設計に対抗する善意のエンジニアの最後の拠りどころ、みたいな使われ方もします。その使い方をむげに否定する気は、私にもありません。要するにビューの使用は、NULL の使用と並んで、開発者の判断力を問われる場面だ、ということを理解してほしいのです。開発の効率性、クエリの可読性、セキュリティ、パフォーマンス、管理の手間、こうした様々な要素を総合的に考慮したうえで、ビューをいかに使うか、使わないか、あるいはマテリアライズド・ビューに乗り換えるか、あるいはインデックスを張ることで対処するか、判断を下さねばなりません。
「銀の弾」がない、という言葉は、悲観的に聞こえるかもしれませんが、それほど悪く受け取ることもありません。ある意味、これは取り組み甲斐のある問題の一つだからです。それにそもそも、銀の弾が見つかってしまったら、多くのエンジニアはきっと廃業の憂き目を見ることになるのですから。
注
[1] 例えば、以下の文章を参照。
- 少なくともリレーショナルモデルに関する限り、実体化されないことこそビューの真髄なのである。 ・・・・・・ したがって、「実体化されたビュー」とは、何とも矛盾した表現である。 (C.J.デイト『C.J.Dateのデータベース実践講義』 p.76)
デイトは上記の箇所で、マテリアライズド・ビューは、ビューよりはむしろスナップショット(ある時点での関係値を保存したもの)の概念を実装したものであり、正確にはビューと呼ぶべきではない、と注意を促しています。確かにその通りなのですが、マテリアライズド・「ビュー」という用語は既にかなり流通してしまっているので、いまさら用語を変更するのは難しいでしょう。当面は、混乱しないよう注意するほかありません。
Copyright (C) ミック
作成日:2002/12/01
最終更新日:2017/06/22 Tweet