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の取得
CakePHPは基本的にはディレクトリそのまま配置することで構築が可能ではありますが、設定パスを変更することでセキュリティに考慮した構成にすることや運用性をもたせたものにすることが可能になります。
-
-
Formヘルパーのinputタグのdiv/labelなどの設定
Formヘルパーのinputではデフォルトでは以下のようにdivで囲われて、labelが付与されて出力されます。 CSSのフレームワークなどであらかじめ決まったスタイルがある場合に便利に作られていま
-
-
コントローラ内でバリデーション処理を呼び出す
CakePHPでは、saveメソッドの際にバリデーション処理も自動で行われますが、save処理と切り離してバリデーションを行うこともできます。このときは、save時と若干異なる処理体系になります。
-
-
hasOne アソシエーション
hasOneアソシエーションはテーブル間で1つのレコードに対して他のテーブルに紐付くレコードが1つの場合にjoinする場合に使用します。 CakePHPのドキュメントにならってUserモデルとP
-
-
バリデーション前後に処理を追加できる「beforeValidate」「afterValidate」
CakePHPでは、「beforeValidate」「afterValidate」というバリデーション処理の前後で追加の処理を実装できるコールバック関数が用意されています。 beforeVali
-
-
Jsヘルパーを使用してAjax更新
更新処理でページ遷移を伴う場合、ページ全体をレスポンスするのに対して、Ajax処理ではページの一部のレスポンスが可能となるためサーバからの通信量を抑えることが可能となります。デモ head
-
-
checkボックスを実装
selectボックスに引き続いてcheckボックスの実装方法をおさらいしてみます。 コードは、CakePHP 2と1.3両方で実装可能です。デモ モデルは、こちらも以下 CREATE TA
-
-
ユーザ登録(仮登録・メール・本登録)
以前1.3版で投稿した「ユーザ登録」処理の2.x版を作成しました。フローは同じで以下のようにします。 1. メールアドレス・パスワードでユーザ登録 2. この時点では仮登録として、本登録用のU
-
-
数値系バリデーション
CakePHP 2になっていくつか数値用バリデーションルールが追加されています。 数値用 (コア)バリデーション decimal - 十進数であること numeric - 数値であること
-
-
多言語サイト向けに翻訳ファイルを使って翻訳を行う
CakePHPには、翻訳をビヘイビアを使用する方法と翻訳ファイルを使用する方法の2つがあるそうです。(他にもあるのかな?) 今回は、翻訳ファイルを使用して言語の切り替えを行い、その言語設定をCook


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/ …