【SQL Server】N+1問題とは何ですか?

N+1問題とは

下記の記事を参考にしました。

qiita.com

ループ処理の中でSQLが大量に実行されて、処理が遅くなることをN+1問題という。

例)

書籍テーブルと利用者テーブルがあり、各書籍に対する利用者情報を取得する場合

書籍テーブルと利用者テーブル

1.SELECT 借用者ID FROM 書籍テーブルで各借用者IDを取得する

2.1で取得した利用者IDをforeach文でループさせる

foreach(var item in 1で取得した利用者ID)のようなイメージ

3.SELECT * FROM 利用者テーブル WHERE 利用者ID = itemで取得した利用者IDに対するSQL文を実行する

のようなステップを踏みます。

3のループ内で1で取得した利用者IDの数分だけSQLが実行されてしまいます。

そうするとSQLの応答が返ってこないことがあります。

 

N+1問題への回避方法

N+1問題を回避する方法は主に2つです。

・JOINをする

・Eager Loadする

 

JOINをする

JOINを使って先ほどのSQLを以下のように書き換えます。

SELECT * FROM 利用者テーブル INNER JOIN 書籍テーブル ON 借用者ID = 利用者ID

こうすることで先ほどの1~3のステップを表現できます。

 

EagerLoadする

事前に取得したデータをIN句を使って一括で取得する方法です。

1.SELECT 借用者ID FROM 書籍テーブルで各借用者IDを取得する

2.SELECT * FROM 利用者テーブル WHERE 利用者ID in (1で取得した借用者ID)で取得した利用者IDに対するSQL文を実行する

こうすることでfor文を使わずに各利用者IDを取得することができます。