45
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CakePHP2のパフォーマンスチューニング(DBとキャッシュ)

Last updated at Posted at 2016-06-24

CakePHPにおけるパフォーマンスチューニングとは

パフォーマンス向上するための方法は大まかに分けて2種類ある

1. ボトルネックとなる処理を探し当てて改善する方法

コードを修正する、パラメータをチューニングするなど。

2. キャッシュを使う方法

処理実行結果をキャッシュに保存することで、2回目にアクセスしたときにその処理を通らずに処理結果を返す事ができる。

DBのパフォチュー

1. 発行しているクエリ数を減らす

<?php echo $this->element('sql_dump'); ?>

これをViewに貼ればカウントできる。減らせるクエリは減らす。

2. findのパフォチュー

極力以下を利用する。

a) 基本的にqueryメソッドが最強。ただし...

コードの可読性が下がるので大量データを取得する必要があるときに利用。場合によってはfieldで取得するより早い。

$this->Hoge->find('all');
$this->Hoge->query('SELECT * FROM .....')

公式ドキュメント

queryメソッドの注意点

同一リクエスト内で同じ内容のクエリメソッドを複数回実行すると、一回目のクエリがキャッシュされるため、一回目以降の実行時の結果はかならず一回目のものと同一になる。

それが嫌なら第二引数にfalseをセットすべし

b) 次点でfieldメソッド

条件にマッチした特定のフィールドのデータのみ取得

$this->Model->field('カラム名', $conditions, $order)

公式ドキュメント

c) それ以外はfind。findByXxxxxは使わない

findByIdとかfindAllByIdを使うより、普通のfindを使った方が早い。

findを利用するときの注意点

  • 使っても良い順: first > count > limit >>>>> all
  • 関係ないデータを取得しないようにかならず recursive を設定する
  • allを使うときは可能なら limit を設定する
  • どんなクエリを発行してるか確認する

3. まだsaveAllで消耗してるの?

saveAllは地雷です。忘れましょう。 saveをforeachした方が早い。

可読性より性能を重視したい箇所ではsaveやsaveAll、updateAllは基本的に使わず、代わりにqueryメソッドを使います。

とある記事の実行結果では以下のようになったらしい

スクリーンショット 2016-06-17 17.04.00.png

(参考)CakePHP2.x系でバルクインサートを使用して高速なインサート処理を実現する

もちろん、可読性は高いので、パフォチューが必要ない場所では使っていいよ。

キャッシュのパフォチュー

これうまいこと活用すればすごいパフォーマンスあがるよ!

Cacheクラスを利用

準備

キャッシュを利用するクラス内でCacheクラスを読み込む

App::uses('Cache', 'Cache');

キャッシュの書き込み

Cache::write($key, $value, $config = 'default');

第三引数のキャッシュの設定は省略可能

キャッシュの読込

Cache::read($key, $confitg = 'default');

有効期限が切れてたりエラーが起こるとfalseが返ってくる

キャッシュの削除

Cache::delete($key, $confitg = 'default');

使い方

public function doSomething() {
	$ret = Cache::read('hoge');
	if($ret !== false) {
	    return $ret;
	}
	$ret = $this->Hoge->find('first');
	Cache::write('hoge', $ret);
	return $ret
}

Viewキャッシュのパフォチュー

Viewのキャッシュ時間を設定する

アクションごとに設定できる。

core.phpにて

Configure::write('Cache.check', true); // コメント外す

Controllerにて

  • キャッシュを利用するViewに対応するControllerにてキャッシュヘルパーを指定
public $helpers = ['Cache'];
  • 以下のように cacheAction を設定することでビュー出力を時間分キャッシュする
public $cacheAction = [
    'index' => '+1 hour', 
    'view' => '+10 minute'
];

部分的にViewキャッシュから除外する

Viewの中で以下のタグを入れればリクエストごとに表示処理が実行される。(リクエストごとにPHPを実行したい場合などに利用)

<!--nocache-->
キャッシュしたくない箇所
<!--nocache-->

Viewキャッシュの削除

以下の3つの場合に削除される

1. 定めた有効期間を過ぎた場合

2. Modelのsaveメソッドもしくはdeleteメソッドを実行した場合

この場合自動でViewキャッシュが削除される。削除されるのはModelの名前に合致するViewキャッシュ。たとえばHogeモデルのsaveメソッドを実行するとHogesコントローラーのViewキャッシュが削除される。

3. clearCache関数を実行した場合

// すべてのViewキャッシュを削除
clearCache();

// HogesコントローラーのViewキャッシュを削除
clearCache('hoges');

Elementをキャッシュする

echo $this->element('helpbox', array(), array('cache' => true));

(公式)エレメントをキャッシュする

(参考)Viewをキャッシュする

その他のパフォチュー

$this->Html->link(); は地雷

地味に思いよ。Htmlヘルパーのlinkメソッドは全てhtmlに置き換えよう。

(おまけ)処理速度計測の方法

以下のコードで囲えば処理にかかった秒数がログ出力されるよ!

$start = microtime(true);

/* ここの処理を計測! */

$end = microtime(true) - $start;
$this->log($end); //ログ出力
45
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?