即時マテリアライズドビューの作成
ここでは、SQL Anywhereに付属しているサンプルのデモデータベースにおける例を見てみましょう。仮に、ProductテーブルをSalesOrderItemsテーブルに結合するマテリアライズドビューを作成するとします。狙いは次の2つです。
-
マテリアライズドビューでProductsとSalesOrderItemsの左外部ジョイン(
LEFT OUTER JOIN)を計算し、すべての商品を含む結果(既存の注文がない商品も含む)を提示すること - 各部品の注文数と、全注文におけるその部品の総出荷数をマテリアライズドビューで計算する
ビューの定義は次のようになります。
CREATE MATERIALIZED VIEW ProductOrders( ProductID,
ProductName, ProductDescription, ProductSize, UnitPrice,
TotalQty, QtyCount, NumberofOrders) AS
SELECT p.ID, p.Name, p.DESCRIPTION, p.SIZE,
p.UnitPrice, SUM(s.Quantity), COUNT(s.Quantity), COUNT(*)
FROM SalesOrderItems s RIGHT OUTER JOIN Products p
ON(s.ProductID = p.ID)
GROUP BY p.ID, p.Name, p.DESCRIPTION, p.SIZE, p.UnitPrice
SUM(s.Quantity)関数が使われているため、即時反映には追加のCOUNT(s.Quantity)が必要となる点に注意してください。
即時ビューの作成には4段階のプロセスが必要です。
- マテリアライズドビューの定義を作成します。新規に作成されたマテリアライズドビューのデフォルトは手動更新に設定されています。
-
マテリアライズドビューに対して、以下の条件を満たすユニークインデックスを少なくとも1つ作成します。
- 外部ジョインを使わない即時マテリアライズドビューでは、インデックスが作成されたカラムはNULLにできない。
-
マテリアライズドビューが外部ジョインを含む場合、ユニークインデックスの宣言には
NULLS NOT DISTINCT句を使う。 -
GROUP BY句を使うマテリアライズドビューでは、インデックスが作成されたカラムはビューの結果において集約関数を参照しない。
-
ALTER MATERIALIZED VIEWを発行して、ビューが即時に更新可能であることを宣言します。 -
REFRESH MATERIALIZED VIEW文を使ってビューを初期化します。この初回以降はサーバーが自動的にリフレッシュします。
以降では、DBISQLを使った各ステップのスクリーンショットを紹介します。まずマテリアライズドビューを作成し、これをProductOrdersと呼ぶことにします。
続いて、ビューに対するユニークなインデックスを作成します。インデックスで参照する必要があるのはProductIDのカラムだけです。ProductIDによって、マテリアライズドビューの射影におけるその他の属性が一意に識別されるからです。ここで新たにWITH NULLS NOT DISTINCT構文が使われていることに注意してください。これはProductIDがNULLのローが1つしか存在しないように保証するためです(もっとも、この例ではProductIDがプライマリキーであるため、そのようなローは存在しません)。
次にALTER MATERIALIZED VIEW構文を発行し、ビューが即時に反映されるようにします。
そして最後に、ProductsOrderedのマテリアライズドビューをREFRESHし、初期インスタンスを作成します。これにより、ProductテーブルまたはSalesOrderItemsテーブルが更新された場合、サーバーはビューの内容を自動的に更新します。
ここではSERIALIZABLE隔離レベルでビューを作成しましたが、データベースでSNAPSHOT隔離レベルを有効化している場合は、そちらを代わりに採用してもかまいません。
ビューマッチング
以上の手順で作成したProductOrdersのマテリアライズドビューは、データベースに変更があるとサーバーによって即時に更新されます。しかし、マテリアライズドビューの真価が最も発揮されるのは、ビューマッチングが行われるときです。ビューマッチングとは、ベーステーブルに対するクエリへの応答に際し、オプティマイザが、マテリアライズドビューのすべてまたは一部を代わりに利用する技術です。SQL Anywhereのビューマッチングに使用されるマテリアライズドビューの定義については、必然的に、即時ビューの制限の上に、さらに追加の制限が課せられます。
ビューマッチングの対象となるビューは、やはり単一のSELECTブロックから構成されていなければなりません。さらに、このSELECTブロックは以下の要素を含んではいけません。
-
GROUP BY GROUPING SETS句、GROUP BY CUBE句、またはGROUP BY ROLLUP句 -
ローを制限する句(
TOP句、START AT句、LIMIT句、またはOFFSET句) -
SELECT DISTINCT句(代わりにGROUP BY句が使用可能) -
完全外部ジョイン(
FULL OUTER JOIN) - セルフジョインまたは再帰ジョイン
Techwave 2010のAnilの講演では、ここで紹介した話だけでなく、SQL AnywhereのMERGE文を使った即時マテリアルビューの反映方法など、もっと多くのトピックを取り上げてくれることでしょう。

