並列クエリを上手に使いこなす!
MERGEテーブルも考慮すべし
「第1回:DBは習うより慣れよ!(http://www.thinkit.co.jp/article/97/1/)」でちょっとだけ触れましたが、MySQLにはMERGEテーブルというものがあります。MERGEという名のとおり、複数のテーブルを引っ付けて、あたかも1つのテーブルであるかのように取り扱うことができます。
同じスキーマ(テーブル構造)のAというテーブルと、Bというテーブルがあったとすると、この2つを連結したCというMERGEテーブルを作成することができます。そして、Cを検索すると、AとBの両方の内容を検索することができます。
MERGEテーブルは、それぞれのテーブルのデータをコピーするわけではなく、それぞれに対するリンクを保持するため、ディスク容量を無駄に消費することはありません。
そして、今回の「並列」という趣旨において大切なことは、テーブルAとテーブルBを、物理的に違うディスク上に設置しておけば、少なくともHDDへのアクセスを並列化することができるので、単純な1テーブルを検索するよりも速度面では有利になります。もちろん、CPUやメモリなどは共有していますから、効果はディスクアクセスに限定されますが、それでも効果はあるでしょう。
また、MERGEテーブルは、実体となる個々の要素のテーブルへのリンクで構成され、MERGEテーブル自体がディスクに占めるスペースがコンパクトであるということは、さまざまな粒度でMERGEテーブルを作成しておくことも現実的であるということです。例えば、ログを格納するテーブルを1ヶ月単位としておき、直近1年分を検索する際には、直近1年分マージしたMERGEテーブルに対して検索を行い、全体に対して検索を行う場合には、全体をマージしたMERGEテーブルを用いるといった使い方ができます。
MERGEテーブルを作成してみる
MERGEテーブルの作成は簡単です。あらかじめ、要素となるテーブル(テーブルA、テーブルBなど)を作成しておきます。MERGEテーブルで結合するテーブル(テーブルA、テーブルBなど)のスキーマは、必ず同一にしておいてください。
MERGEテーブルを作成するには、CREATE TABLE構文を以下のように記述するだけです。
CREATE TABLE [マージテーブル名] (
...
) TYPE=MRG_MyISAM UNION=([テーブルA],[テーブルB]) INSERT_METHOD=LAST;
テーブル定義は省略していますが、ポイントは最後の行です。TYPE=MRG_MyISAMでMERGEテーブル型を指定し、またUNIONでどのテーブルを結合するかを指定します。最後にINSERT_METHOD で指定したテーブルのうち、どれに書き込むかを指定します(FIRSTかLASTで指定します)。
1点注意があるとするならば、PRIMARY KEYとなっているキーについて、各要素となるテーブルの中では重複していなくても、これをマージすることで重複する場合が生じます。例えば、テーブルA、Bそれぞれに、IDが1というレコードは1つしかないとしても、これをマージした瞬間に、IDが1というレコードが2つ存在することになります。このため、マージすることが分かっている場合には、PRIMARY KEYが重複しないように付番しておくなどの工夫が必要です。
5回にわたり、並列クエリについて紹介していきました。第1回のタイトルにもありますが、データベースは「習うよりも慣れろ」ですから、ぜひ、いろいろなシーンで活用してみてください。