FANCOMI Ad-Tech Blog

株式会社ファンコミュニケーションズ nend・新規事業のエンジニア・技術ブログ

DboSource::getLog()で発行されたSQLを確認する

h_nagayamaです。 CakePHPでは、DboSource::getLog()を使用すると、発行されたSQLを確認することができます。 私は下記のように使用しています。 ※以降は CakePHP 1.3 のソースです [js] debug($this->{$model}->getDataSource()->getLog()); [/js]

こちらは大変便利な機能なのですが、getLog()は、デフォルトで200件までしか出力してくれないようです。 件数の制限がかかっており、制限値を超えた時点で、出力用配列への追加がスキップされてしまうためです。

cake\libs\model\datasources\datasource.php [js] /* * Maximum number of items in query log * * This is to prevent query log taking over too much memory. * * @var int Maximum number of queries in the queries log. * @access protected /

$_queriesLogMax が制限値です

var $_queriesLogMax = 200; [/js]

cake\libs\model\datasources\datasource.php [js] /* * Log given SQL query. * * @param string $sql SQL statement * @todo: Add hook to log errors instead of returning false * @access public / function logQuery($sql) { ## DboSource::execute()が実行される度 ## logQueryが呼び出されて、発行したSQLを出力用変数に格納しています $this->queriesCnt++; $this->queriesTime += $this->took; $this->queriesLog[] = array( 'query' => $sql, 'error' => $this->error, 'affected' => $this->affected, 'numRows' => $this->numRows, 'took' => $this->took ); ## ここで $queriesLogMax を超えてしまっている場合には ## $this->queriesLogに追加されなくなっています if (count($this->queriesLog) > $this->queriesLogMax) { array_pop($this->queriesLog); } if ($this->error) { return false; } } [/js]

大量にSQLを発行している処理で、getLog()を使用したい場合には $_queriesLogMax の設定値にも注意が必要になります。

CakePHPのソースをgrepした結果、$_queriesLogMax の設定値を変更するメソッドは用意されていないようです。

DboSource::getLog() は引数を受け付けます。 cake\libs\model\datasources\datasource.php [js] /* * Get the query log as an array. * * @param boolean $sorted Get the queries sorted by time taken, defaults to false. * @return array Array of queries run as an array * @access public / function getLog($sorted = false, $clear = true) { if ($sorted) { $log = sortByKey($this->queriesLog, 'took', 'desc', SORT_NUMERIC); } else { $log = $this->queriesLog; } if ($clear) { $this->queriesLog = array(); } return array('log' => $log, 'count' => $this->queriesCnt, 'time' => $this->_queriesTime); } [/js]

第1引数にtrueをセットすると、時間のかかっているSQLを降順に並び替えてくれます。 第2引数にtrueをセットすると、出力用変数が初期化されます。

SQLまわりをデバッグする際には、ぜひ試してみて下さい。