いろいろ備忘録

雑記です。

CakePHP3のORM\table::find()のイーガーロードとは

  • contain 関連をイーガーロード (eager load) するように定義します。

データの取り出しと結果セット

イーガーロードとは、N+1問題を回避する手段らしい。

 

まず、N+1問題とは?

ユーザーマスタと、著者のユーザIDを属性としてもつ記事テーブルがあるとします。

ブログのトップページに記事タイトルとユーザー名を並べて表示したいとき

SELECT 記事.タイトル, ユーザー.名前 FROM 記事, ユーザー
WHERE 記事.ユーザID = ユーザー.ユーザーID というSQL文が実行されそうですが、

実際は SELECT * FROM 記事 が最初に実行されます。

その後、その結果行(CakePHP3でいうとエンティティ)ごとに線形に 
SELECT * FROM ユーザー WHERE ユーザーID = 7 
SELECT * FROM ユーザー WHERE ユーザーID = 4
などとSQLが実行されます。

つまり、2つ以上のテーブルをSQLで関連付けているとき、最初に1クエリとその結果行のN行分のクエリが実行されてしまう問題です。

これを回避するために、N回あったユーザーテーブルへのSQLを一度にまとめます。
SELECT * FROM ユーザー WHERE ユーザーID = IN(7,4,0,1,40,21, ... , 90)

これがイーガーロードです。