2005年6月 3日
連想配列
PHPとかPerlの連想配列は結構速い。
C言語で育っていると、どうも連想配列を使うという発想が出来ない。C言語だけで実現しようとすると、自力でメモリ配列を考えなきゃならんし、追加削除でmalloc()とかfree()とかしてたらメモリリーク起こしそうだし、数が増えたらハッシュでキーを付けるとかして高速化しないと使い物にならない。出来れば有限個のまっすぐな配列だけで済ませたいとか思ってしまう。
ところがPHPなどでは、とにかく何でも連想配列にぶち込むのがいい。数千件ならサクッと入って、キーから引いてくるのも一瞬。昔はメモリの心配もしなければならなかったが、今は数メガ程度のデータをメモリ上に持ってもなんら不都合は無い。
今日のお仕事で、無茶苦茶遅いSQLがあった。数百万行のテーブルと、数千行のテーブルをジョインしている。ジョインしているのはIDから名前に変換しているだけなのだが、やたら遅い。ジョインしなければ一瞬で返ってくるんだが・・・。
joinしないで結果を取得し、IDから名前に変換するのは1つ1つSQLを発行しなおす、という手もある。しかし、クエリの回数が増えるのはかなりオーバーヘッドが高い。
そこで、IDから名前に変換するテーブルは全件取得し、連想配列にぶち込んでみた。数千件なら一瞬である。そして、表示時にその連想配列を使ってIDから名前に変換する。オンメモリなのでこれも速い。
これで1〜2分かかっていた画面表示を1秒程度に高速化できた。
Java Servlet で作っていたなら、この ID-名前 変換テーブルというか連想配列というか Hashtable を init() の中で作ってメモリに置きっぱなしにすると良いかもしれない。DB更新時に、Hashtableも同期しなければならないという手間・バグのリスクがあるので安易には採用できないけど。利用頻度によってはかなり高速化できると思う。
このエントリーのトラックバックURL:
http://weblog.rukihena.com/mt/mt-tb.cgi/97