MySQLでマテリアライズドビュー9 実装編 参照更新(on demand)

Oracleのマテリアライズドビューのパターンにない方法として、SELECT文実行前にマテリアライズドビューを更新するという方法がある。このパターンはon demandの一種でマテリアライズド・ビューの更新が滞っていると、参照までに時間が掛かるという弱点はあるものの、参照が必要になったときに、まとめて更新されるため更新の効率はよい。定期更新 + 参照更新といった組み合わせで使うと効率的です。そこで、前エントリーで紹介したSELECTトリガーを使ってこれを試みてみます。

  • ストアドファンクションを作成します。
DROP   FUNCTION comment_materialized_insert_select_trigger;
delimiter //
CREATE FUNCTION comment_materialized_insert_select_trigger(
ret INT ) RETURNS int 
BEGIN
  call comment_materialized_insert();
  RETURN ret;
END
//
delimiter ;
  • 擬似SELECTトリガー実行
SELECT * FROM mv_comment WHERE comment_materialized_insert_select_trigger(1)

ERROR 1442 (HY000): Can't update table 'mv_comment' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

Oracleの場合と同じで、同一テーブルへの更新はブロックされてしまいました。Oracleの場合と違ってMySQLには文トリガー(FOR STATEMENT)もないので回避不能です。

結局、以下のように素直にアプリケーション側でSELECT文の前にストアドプロシージャを実行することで落ち着きました。

call comment_materialized_insert();
SELECT * FROM mv_comment

よくよく考えると、文トリガーは、SELECT、INSERT、UPDATE、DELETE、の文(STATEMENT)の前後(BEFORE、AFTER)にストアドプロシージャを呼ぶ(CALL)すればいいだけなので、MySQL的には、そんなのアプリケーション側で実装しろよということなのかもしれませんね。