LoginSignup
0

More than 3 years have passed since last update.

CodeIgniter の DB_Driver (save_queries) にご注意【vol.1】

Last updated at Posted at 2019-06-18

株式会社オズビジョンのユッコ (@terra_yucco) です。
CodeIgniter の DB_Driver 及び config/database.php をデフォルト設定のまま使っていたので、DB オブジェクトを引き回しすぎてバッチ処理がメモリ不足で乙りました。というお話。

CodeIgniter

PHP の軽量フレームワークです。

DB_Driver

名前の通り、DB に接続するためのあれこれが詰まったクラスです。
この中の save_queries で今回嵌りました。

定義部分

    /**
     * Save queries flag
     *
     * Whether to keep an in-memory history of queries for debugging purposes.
     *
     * @var bool
     */
    public $save_queries        = TRUE;

利用箇所

上記コードから抜粋

この処理の少し前で SQL を作って $sql に入れている。
作成した $sql はこのインスタンスの寿命がある限りどんどん追加されていく。

        if ($this->save_queries === TRUE)
        {
            $this->queries[] = $sql;
        }

その他、実行時間も以下のような 2 箇所で保存。

クエリ発行失敗時。

        // Run the Query
        if (FALSE === ($this->result_id = $this->simple_query($sql)))
        {
            if ($this->save_queries === TRUE)
            {
                $this->query_times[] = 0;
            }

クエリ発行成功時。

        if ($this->save_queries === TRUE)
        {
            $this->query_times[] = $time_end - $time_start;
        }

これもどんどん領域に追加されます。

対処するには

以下のようにすればよいと思われます。最後のところだけ、オリジナルのコードは TRUE ですが false にしています。

$db['default'] = array(
    'dsn'   => '',
    'hostname' => 'localhost',
    'username' => '',
    'password' => '',
    'database' => '',
    'dbdriver' => 'mysqli',
    'dbprefix' => '',
    'pconnect' => FALSE,
    'db_debug' => (ENVIRONMENT !== 'production'),
    'cache_on' => FALSE,
    'cachedir' => '',
    'char_set' => 'utf8',
    'dbcollat' => 'utf8_general_ci',
    'swap_pre' => '',
    'encrypt' => FALSE,
    'compress' => FALSE,
    'stricton' => FALSE,
    'failover' => array(),
    'save_queries' => false, #TRUE
);

実は注意書きもあった

['save_queries'] TRUE/FALSE - Whether to "save" all executed queries.
NOTE: Disabling this will also effectively disable both
$this->db->last_query() and profiling of DB queries.
When you run a query, with this setting set to TRUE (default),
CodeIgniter will store the SQL statement for debugging purposes.
However, this may cause high memory usage, especially if you run
a lot of SQL queries ... disable this to avoid that problem.

['save_queries'] true または false
実行されたすべてのクエリを保存するかどうか。
メモ:これを false にすると last_query() が使えなくなり、またクエリのプロファイリングも使えなくなる。
この設定が true の状態でクエリを走らせると CodeIgniter は SQL ステートメントを debug のために保管する。しかし、特に実行クエリが多い場合、メモリ使用量の高騰の原因になるので、その場合はこの項目を無効にしてその問題を回避してください。

Conclusion

last_query() が使えなくなるのは地味に痛いので、環境によって変更したり、接続単位で変更してあげるなどの工夫は必要そうです。
ただ、本番環境でデバッグ情報を大量に保持する必要はないので、基本的には設定を切っていきたいなと思った次第…。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0