ふんばりフロントエンジニアのブログ

新米フロントエンジニアの備忘録です。ふんばり温泉タオル欲しい...

LaravelでPostgreSQLでもコネクションプーリングする方法

最近めっちゃLaravel使ってます。

で、Laravelのコネクションプーリングの話です。

コネクションプーリングとは、DBとの接続を永続化させること。

フレームワークによっては、これがデフォルトで永続化されているものもあるようですが、Laravelの場合はデフォルトで永続化がオフになっています。

DBとの接続の永続化、というと語弊があるかもしれないので補足しておくとPDOオブジェクトのインスタンス化時の接続をキャッシュしておく、といったほうが良いでしょうか。

これによって、毎回クエリ実行時に接続をする必要がなくなるのでオーバーヘッドが短縮され、高速化される、というわけですね。

あまり必要に感じる場面には出くわさないかもしれませんが...笑

で、Laravelでコネクションプーリングを有効にする設定が下記です。

 'pgsql' => [
            'driver' => 'pgsql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '5432'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
            'prefix_indexes' => true,
            'schema' => 'public',
            'sslmode' => 'prefer',
            'options' => [
                PDO::ATTR_PERSISTENT => true,
            ],
        ],

デフォルトとの変更点は、optionsの部分です。

「PDO::ATTR_PERSISTENT」を追加することで、接続を永続化することができます。

mysqlの例しかなかったので、PostgreSQLではできないのかと思っていましたが、そんなことはなかったですね。

永続化できているかどうかの確認は、下記手順で確認できます。

  1. php artisan tinker
  2. DB::connection()->getPdo();

出力結果の「PERSISTENT」がtrueになっていれば永続化できています。

余談

コードを追っていただくとわかるのですが、「src/Illuminate/Database/Connectors/Connector.php」がコネクションを作成しているクラスになっています。

その中に、下記のような記述があります。

/**
     * Create a new PDO connection instance.
     *
     * @param  string  $dsn
     * @param  string  $username
     * @param  string  $password
     * @param  array  $options
     * @return \PDO
     */
    protected function createPdoConnection($dsn, $username, $password, $options)
    {
        if (class_exists(PDOConnection::class) && ! $this->isPersistentConnection($options)) {
            return new PDOConnection($dsn, $username, $password, $options);
        }

        return new PDO($dsn, $username, $password, $options);
    }

    /**
     * Determine if the connection is persistent.
     *
     * @param  array  $options
     * @return bool
     */
    protected function isPersistentConnection($options)
    {
        return isset($options[PDO::ATTR_PERSISTENT]) &&
               $options[PDO::ATTR_PERSISTENT];
    }


まあ、見ての通りなのですがoptionsのkeyにPDO::ATTR_PERSISTENTがセットされていれば、永続化されるようになっています。

公式ドキュメントには記載されていない部分ですが、同じ場面に出くわした時助けになれば嬉しいです。