「ひとつのキー に、まとめてデータを入れるとオーバーヘッドがかかるかもしれないよ」
と教えられ、現在ひとつのキーに入れないような設計をしている最中で、
じゃあ、試しに、1,000の値 を、
ひとつのキーに全データをシリアライズして入れる
1,000のキーとして入れる
というそれぞれの方法では、実際にどれだけオーバーヘッドの可能性があるかどうか。
ターゲットは wp_options
オーバーヘッドは一切ありません。
テーブル一覧
ここで挿入する値の定義
1,000個の1~10,000,000の乱数を作成して挿入
つまり、
array(
0 => 2384、093,
1 => 6923230,
2 => 8053892,
...
999 => 1034544
);
のようなデータです。
データには日本語や英文が入る場合が多いので、今回はデータ量が少ない気がして、
良いテストかどうかと聞かれれば、分かりません。としか答えられませんが、
少しぐらいは何か分かるのではないかと思い、やってみることにしました。
wp_options にまずは、ひとつのキーに1,000の配列を挿入することを仮定して、試してみました。
$SampleData = array();
for( $i=0; $i<1000; $i++ ) {
$SampleData[$i] = rand( 1 , 1000000 );
}
print_r($SampleData);
print_r で値を確認。1,000の配列が出来ています。
これを、wp_optionsへひとつのキーとして、シリアライズしたデータをupdate_optionで挿入してみると、
ひとつのキーに挿入
ぎっしりはいりました。結果…
オーバーヘッドはなし。
えっ? これじゃ検証にならない。。もっとデータ量を増やして試してみよう。
ということで、オーバーヘッドされるまで、データ量を増やしながら色々と試行錯誤…。
結果。どんなに頑張ってもオーバーヘッドしなかった。。
参ったなぁ。指摘されているから、オーバーヘッドするはずなんだけど…
実際にオーバーヘッドしているテーブルがあったので、そのテーブルとひたすらにらめっこ。
すると、気づきました…。
データ型
MyISAM
ん?「MyISAM 」?私のイサム?メルティーラブ??
軽めにググってみました。
あ、データベースにも色々とデータの種類があるのね。全く知りませんでした。
で、さっそくテスト環境に使っているテーブルの型を、MyISAMに変更。
同じように1,000個の値を持つ乱数配列で再度update_optionでデータを挿入すると…
でました。オーバーヘッド。
ひとつのキーに挿入時
ひとつのキーに、1,000個の、乱数で作成された値をもつ配列を、シリアライズして挿入すると、
29.5 KiB (KiBって何?キロバイトじゃなくて?)
計10回、挿入してみましたが、 29.5 KiBから変わらなかったです。
なるほど。何度も値を挿入しても、値は変わらないのか。配列の値も色々と変えてみる。
ここまでで分かったこと
× 1回のオーバーヘッド量 29.5 KiB × 10回updateすると = 295KiB になるわけではなく、
○ 挿入するデータ量に応じて、オーバーヘッドのサイズが変わる。何度更新しても。
そっか。
これじゃあ何度テーブルの最適化をしても、そのupdateをする限りいつまでもオーバーヘッドするじゃないか。
よし。
次の検証にうつります。その前に、オーバーヘッドの最適化。
次は、1,000のキーとして、値を挿入。の検証
挿入するデータは以下。
for( $i=0; $i<1000; $i++ ) {
update_option( 'sampledata' . $i , rand( 1 , 1000000 ) );
}
結果は。オーバーヘッドなし
確かにこの方法がいいかもしれない。
ん?ちょっとここでもうひとつ試してみることにしました。
update_optionの値を、ただの配列にするとどうなるか
for( $i=0; $i<1000; $i++ ) {
update_option( 'sampledata' . $i , array( rand( 1 , 1000000 ) ) );
}
結果はこちら。
値を配列に変更後
20 バイト。配列にするだけで、オーバーヘッドが起こるのか。
wordpress の update_option()の流れとしては(ざっくり)、
update_option() の値に配列やオブジェクトをつっこむ
maybe_serialize() という処理が入る
この”たぶん、シリアライズ機能”のほうで、
if ( is_array( $data ) || is_object( $data ) )
return serialize( $data );
シリアライズされたデータを返し、データベースのデータが更新されます。
じゃあ、配列でupdate_optionデータを更新する限り、シリアライズ される。
シリアライズされたデータ で、 データベースの型が MyISAM なら、ほぼオーバーヘッド が起こる。
(データベースの環境も左右されるかもしれませんね)
いい勉強になりました。
オーバーヘッドを避ける為には、1キーに1つの値。
という事ですね。
今公開中のプラグインは、ほとんどがシリアライズされたデータなので、いくつかは変更する予定です。
>>追記
実際には、1キー に 1つの値 にしても、オーバーヘッドを避ける事はできませんでした。
どういう事かというと…
作成したキーを、削除するだけでもオーバーヘッドが出ました。
また、コメントでbloger323さんがおっしゃる通り、データの増減が激しい場合もオーバーヘッドが出るようです。
うーん、どういう構造がいいんでしょうね。。