目次
バッチ処理でセグメンテーション違反発生
CodeIgniterフレームワークで運用しているWEBサイトで、バッチ処理をしている際に、以下のようなメモリ不足エラーが発生していた。「セグメンテーション違反」といったエラーが出ていた。
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) in /path/to/mysite/system/database/drivers/mysqli/mysqli_result.php on line 222
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) in /path/to/mysite/system/database/drivers/mysqli/mysqli_result.php on line 222
first_row()は一回結果をメモリに取得してからfirstする
調査してみると、原因は、DBでデータを取得するコードの書き方に問題があった。以下コードがそう。
1 2 3 |
$this->db->select('column1, column2'); $this->db->order_by('column3', 'desc'); $this->db->get('my_table')->first_row('array'); |
ここで、my_tableは、大量にデータがあるテーブルだったのだが、上のコードだと、テーブルのデータをすべてSELECTしてメモリに読み込もうとしていた。
対応は以下のコード。単純にlimitをつけただけ。
結果、問題が解決しただけでなく、バッチ処理が終わるのがスーパー早くなった。
1 2 3 4 |
$this->db->select('column1, column2'); $this->db->order_by('column3', 'desc'); $this->db->limit(1); $this->db->get('my_table')->first_row('array'); |
CodeIgniterのソース読んでみたけど、first_rowって、1レコードだけメモリに読み込むのかと思ったら、全レコード取得してから、先頭要素を取得していた。
勘違いしてたー!
コメント