即時マテリアライズドビューの作成
ここでは、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
文を使った即時マテリアルビューの反映方法など、もっと多くのトピックを取り上げてくれることでしょう。