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


h_nagayamaです。
CakePHPでは、DboSource::getLog()を使用すると、発行されたSQLを確認することができます。
私は下記のように使用しています。
※以降は CakePHP 1.3 のソースです

debug($this->{$model}->getDataSource()->getLog());

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

cake\libs\model\datasources\datasource.php

/**
 * 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;

cake\libs\model\datasources\datasource.php

/**
 * 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;
	}
}

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

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

DboSource::getLog() は引数を受け付けます。
cake\libs\model\datasources\datasource.php

/**
 * 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);
}

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

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

Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*