recursive設定によるfind()性能改善
CakePHPでは、モデルにアソシエーションを設定している場合、recursive(=>joinする階層)はデフォルトで0に設定されています。「recursiveゼロ」の意味するところとは、「1跨ぎまでのJoinを行う」ということになり、Find()関数を使用した場合、デフォルトの状態でJoinが行われてしまいます。テーブル単体でfindしたい場合などは、find()の前に$recursive = -1とすることで余計なjoin処理を省略することができます。join先のテーブルのレコード数が多い場合などは効果絶大。
例
「User」とそれに紐付く「Usercomment」モデルを用意しました。
-- usersテーブル CREATE TABLE IF NOT EXISTS `users` ( `id` INT NOT NULL AUTO_INCREMENT , `username` VARCHAR(50) NOT NULL , PRIMARY KEY (`id`) ) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_general_ci
-- usercommentsテーブル CREATE TABLE IF NOT EXISTS `usercomments` ( `id` INT NOT NULL , `user_id` INT NULL , `commment` TEXT NULL , PRIMARY KEY (`id`) ) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_general_ci
アソシエーションの設定。user(ユーザ)がいて、それに紐付くusercomment(ユーザのコメント)
// Userモデル class User extends AppModel { var $name = 'User'; var $hasMany = array( 'Usercomment' => array( 'className' => 'Usercomment', 'foreignKey' => 'user_id' // 省略可 ), ); }
実行結果
$recursive = 0 でfind
findのみの場合、User(usersテーブル)へのselectと、それに対するUsercommment (usercommentsテーブル)へのjoinが行われます。
// コード $this->data = $this->User->find( 'all');
-- SQLログ queryLog = Array ( [query] => SELECT `User`.`id`, `User`.`username`, `User`.`password`, `User`.`status`, `User`.`created`, `User`.`modified` FROM `users` AS `User` WHERE 1 = 1 [error] => [affected] => 4 [numRows] => 4 [took] => 1 ) queryLog = Array ( [query] => SELECT `Usercomment`.`id`, `Usercomment`.`user_id`, `Usercomment`.`commment`, `Usercomment`.`status`, `Usercomment`.`created`, `Usercomment`.`modified` FROM `usercomments` AS `Usercomment` WHERE `Usercomment`.`user_id` IN (1, 2, 3, 4) [error] => [affected] => 0 [numRows] => 0 [took] => 1 )
$recursive = -1 でfind
findの前にrecursive = -1を設定すると、User(usersテーブル)へのselectのみが行われるようになります。
// (1) [read, findByなど] $this->User->recursive = -1; $this->data = $this->User->find( 'all'); // もしくは // (2) [findByなど] $this->data = $this->User->find( 'all', array( 'recursive' = '-1'));
-- SQLログ queryLog = Array ( [query] => SELECT `User`.`id`, `User`.`username`, `User`.`password`, `User`.`status`, `User`.`created`, `User`.`modified` FROM `users` AS `User` WHERE 1 = 1 [error] => [affected] => 4 [numRows] => 4 [took] => 1 )
SQLクエリーをログに出力する
設定箇所
考え方次第ですが、代表的には以下の2つが考えられると思います。
$recursive = -1をデフォルトに
この場合、joinが必要な場合はfindを行う際に、recursive = 0などに設定をする必要があります。
// app/Model/AppModel.php class AppModel extends Model { public $recursive = -1; }
find毎に$recursive = -1設定
今回試した例です。
個人的には、2を選択しています。
SQLのログは試験中は出力しておいて、余計な呼び出しは省略していくというのは、特にフレームワークを使用する際は注視して使用すると、もっと使い勝手がよくなると思います。もちろん、本番向けは取り除いて下さい。性能劣化につながりますので。。
2.1 / 2.2 / 2.3 / 2.4
関連記事
-
(メール・URL・電話・郵便・IP) データ バリデーション
今回は、プロフィール情報に使用されるデータに絞ったバリデーションルールです。 バリデーションルール 以下の5つのバリデーションルールがコアに用意されています。 email メールアドレス
-
Formヘルパーのinputタグのdiv/labelなどの設定
Formヘルパーのinputではデフォルトでは以下のようにdivで囲われて、labelが付与されて出力されます。 CSSのフレームワークなどであらかじめ決まったスタイルがある場合に便利に作られていま
-
FullCalendarを使用してカレンダーアプリケーション
カレンダーアプリケーションを作成するため、カレンダー表示できるプラグインを探索して出会ったFullcalendarを試してみました。シンプルに使用できる上に、オプションがかなり豊富です。ダウンロード
-
Blowfishを使用してハッシュ化する
使用方法 Blowfishを採用してハッシュ化を行う場合、Securityクラスのhashメソッドを呼び出します。第2引数に'blowfish'を指定し、第3引数を指定しないもしくはfalseにしま
-
日付・時間のバリデーション
日付や時刻に関するバリデーションは以下のルールがビルトインされています。 date 日付 time 時刻 datetime 日時 (m:「月」を数字表記 / M:「月」を英語表記)
-
CakePHP インストール時エラーの対処
CakePHPインストール時に出くわすであろうエラーの原因と対処方法についてまとめてみました。前提として、WebサーバはApache、データベースはMySQLとしています。 Timezone未設
-
CakeEmailでメール送信(@gmail)
CakePHP 2になって追加されたクラスCakeEmailがシンプルに使えます。これを使用してメール送信を行う処理を実装してみました。 CakeEmailクラスの読み込み /app/Config
-
ネストしたリストを出力「nestedList」
DBやJSONからデータを取得して、そのデータをもとにメニュー表示などネストしたリストを出力させたい場合に「nestedList」が便利です。 ヘルパーに渡すデータは連想配列である必要があります。(
-
コントローラ内でバリデーション処理を呼び出す
CakePHPでは、saveメソッドの際にバリデーション処理も自動で行われますが、save処理と切り離してバリデーションを行うこともできます。このときは、save時と若干異なる処理体系になります。
-
SQLクエリーをログに出力する
SQLのクエリーをデバッグするには、Debug Kitを使用すればできますが、デバッグログと一緒に出したいのでやり方を調査してみました。 別々のログやビューでみるのもいいですが、秒単位で実行される処
Comment
cakephp2系では、デフォでrecursive = 0; になってて、1つ跨ぎまでのJOINが自動でされちゃう。それを勝手にJOINされない様にすれば性能上がるよねって話
recursive設定によるfind()性能改善 http://t.co/AIRF8K7lmb
recursive設定によるfind()性能改善 http://t.co/sXQQz89rv9 #pocket2twitter
recursive設定によるfind()性能改善 http://t.co/EdsEJ4COf2
おーん。んるほど http://kwski.net/cakephp-2-x/1180/ …