とあるシステムである特定の処理が遅いと指摘をうけていました。
ある条件になると、処理時間が超過してしまいブラウザタイムアウトとなってしまい、処理が終了しないという状況になります。
さて、原因についてですが、まず条件というのが、処理件数が多くなってしまうということなのですが、処理件数が多いと処理に時間がかかるのはしょうがない。
処理の概要ですが、データベースから条件を指定して抽出を行い、その抽出したデータにさらにPHP側で処理を行うというものです。
ここで時間がかかっていたのは、データベース側ではなくPHP側です。
当初、データベース側で複雑な条件を指定すると時間がかかるため、PHP側の処理に変更したのですがどうもPHP側にすると遅いという状況でした。
この遅くなるという部分の処理ですが、チェック用の配列Arrayの中にデータベースから取り出した値が存在するかチェックを行ってTRUEならば、チェック用の配列に値を格納。これを繰り返すという内容なのですが、このチェック用の配列が1000件近くになると極端に遅くなるんです。
では、どうすればいいか。
方法としては、二つあります。
- 1つは、この配列がある程度、例えば100件程度になれば別の配列に格納する。ただ、この方法だと配列の全件チェックはできないのでNG.
- 2つ目は、配列ではなくデータベースに格納する。
この方法だと、処理件数が少ないと遅くなるのですが、処理件数が多くなると全件チェックはSELECT文一つで完結するので、早くなる。
データベースはMySQLなので、ストレージエンジンはHEAPを選択しようと思ったのですが、HEAPはメモリ上にデータを格納する性質上、MySQL終了時にクリアされる。
しかし、クリアされるのはレコードのみで、テーブルは残ってしまう。
将来的に、件数が肥大してメモリ圧迫も困るので結局MyISAMを選択しました。
さてさて、結果はまず150秒ほどかかっていた処理が30秒ほどになりました。
そして、タイムアウトになっていた処理も200秒程度で処理が完了します。
今回のことで、データが多く大きくなると格納する変数、配列も考慮しておかないといけないのだなと実感しました。
たぶん、Cを経験されている方はメモリの管理も含めて開発しているのでしょうから、今回のようなトラブルは開発時点で分かっていることなんでしょう。
まだまだ、未熟だと実感しましたOTL
【WEB開発】コメントする