Kodougu では、SQL の Select における N+1 問題を回避することが重要になってきます。

N+1 問題とは、Tree 状の情報を DB から読み出す際、全レコードの取得に一つ+各レコード分だけ SQL を発行してしまう問題です。出来の良い O/R マッパーを使っているとよく引っかかります。

Kodougu のようなモデリングツールだと、この問題には非常によく出くわします。例えば、図上の要素を全て取得してから、要素に関係する関連の一覧を取得するなどを行うような場合です。Rails の ActiveRecord は気軽に DB にアクセスできてしまいますから。以下のコードでは、要素から出て行く関係線の一覧を取得しています。以下のようなコードを書いてしまうと、図を一枚描くたびに要素数分の SQL が発行されてしまいます。
[code: @elements = Element.find(:all) # DB アクセス発生

for element in @elements
@outputs = element.outputs # DB アクセス発生
end]

この問題が深刻な理由は、「DB サーバはアプリケーションサーバと比較するとスケールさせにくい」からです。昨今の流行りでは、アプリケーションサーバはステートレスですから、ロードバランサーを入れるだけで簡単にクラスタリング可能です。しかし、DB サーバはレプリケーションに対応していたとしても、同期の問題などがあり単純にスケールさせることは非常に難しいのです。そこで、アプリサーバで CPU パワーを多少使ってもかまわないから、DB への負担を減らしておいた方が、スケールするアプリが書けるというわけです。

今のところ、Kodougu では個別ケースの対処ではありますが、DB にアクセスするときに、必要な情報を DB から全て取得してから、アプリケーションサーバ(Rails)やクライアント(JavaScript)でオブジェクトグラフを再構築してアプリで利用するということをやっています。

この問題をある程度自動的に回避するライブラリを作らないと身が持たないかも・・・。
# 実現方法についてはまだノーアイディアですが・・・。

Posted by あかさた
最近のエントリ
最近の読書メモ