愛犬のダックスをサマーカットし過ぎて失敗した nakajiman です。毛並みがチクチクして痛いのです。
CakePHP 3.4 ORM がどんなクエリを発行しているのか調べてみます。まず、簡単なところで、レコードが存在するかどうか調べる exists を見てみます。
Cake Console を使います。CakePHP のバージョン は、次のとおりです。
$ bin/cake console >>> use Cake\Core\Configure; >>> Configure::version(); => "3.4.9"
続けて Cake Console でクエリログを表示する ようにします。
>>> use Cake\Log\Log; >>> Log::config('queries', ['className' => 'Console', 'stream' => 'php://stderr', 'scopes' => ['queriesLog']]); >>> $cm = \Cake\Datasource\ConnectionManager::get('default'); >>> $cm->logQueries(true);
Users テーブルにある ID を持つレコードが存在するか exists で確認してみます。
>>> use Cake\ORM\TableRegistry; >>> $User = TableRegistry::get('Users'); >>> $User->exists(['id' => 1]);
次のようなクエリが発行されました。SELECT 1 は、まったくデータをフェッチしないということですね。また LIMIT 1 で走査する範囲を最小にしてますね。CakePHP 1.3 だと COUNT 句を使っていて、スケールしたら死亡フラグが立ってたんですが、これなら安心ですね。
SELECT 1 AS `existing` FROM users Users WHERE id = 1 LIMIT 1
ソースコードも確認してみます。お、Hydration を無効にして、Entity を生成しないようにしてますね。ソースコードレベルでもコストを抑える工夫がされてます。
/** * {@inheritDoc} */ public function exists($conditions) { return (bool)count( $this->find('all') ->select(['existing' => 1]) ->where($conditions) ->limit(1) ->enableHydration(false) ->toArray() ); }
といった感じで CakePHP 3.4 の exists は、なかなかの好印象でした。