36
25

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 3 years have passed since last update.

ぐるぐるSQLという用語は止めてくださいという話

Last updated at Posted at 2021-01-19

はじめに

@abe_masanori さんが

という記事を書かれたのですが、そこで「ぐるぐるSQL」なる見慣れない用語が使われていて、それは「N+1問題」というのだとコメントを書いたところ、妙に反発を受けてしまったので改めて記事にしたいと思います。

用語としてどちらが古いか?

さしあたり「ぐるぐるSQL」と「N+1問題」の用語のどちらが正しいかの議論は後回しとして、それぞれの用語の初出を調べてみましょう。例えばtwitterで検索すると、「ぐるぐるSQL」の最古のツイートはこちらのようです。

2008年6月3日だそうです。

一方、「N+1問題」は英語ではそのまま N+1 Problem または N+1 SELECT Problem といい、ツイッター上にはたくさん残っています。

さしあたりこのツイートを選んでおきましょう。

2008年5月15日だそうです。

残念ながらtwitterのサービス自体が2007年頃に生まれたものなのでそれ以外の記事はインターネット上から探すしか無いでしょう。いい記事をご存知でしたらコメントでお知らせください。

「ぐるぐるSQL」という用語はどこがまずいのか

これは元記事でコメントとして書いたように、「ぐるぐるSQL」という用語では日本語の記事しか検索できず、英語の記事が探せないというところになります。はじめから「N+1問題」で統一しておけば、英語の記事を探すときも N+1 Problem でそのまま検索できるわけです。

「ぐるぐるSQL」のほうがわかりやすいという意見

といった擁護意見もあり、最終的にはこれらの用語を使う個々人の判断になるでしょう。

「ぐるぐるSQL」は「N+1問題」と違う定義だという意見

@abe_masanori さんはコメント上でこのように書いています。

今回の問題は N+1 問題とは異なるという認識の元、N+1 問題というワードは意識して使っていません。

N+1 問題というワードは 2000-2010 年代半ば(後半?)ぐらいから使われ始めたと記憶していますが、その文脈は Hibernate や RoR といった SQL 文を開発者に(あまり)意識させない ORM において、DB上の1対多のエンティティをアプリ上の1対多のオブジェクトに(ほぼそのまま)マッピングする際に、ORM 内部で暗黙的に SQL 文が繰り返し呼び出されてしまう状況だったと認識しています。

勿論、ORM にも Eager Fetch や JOIN Fetch など、この問題を解決する手段は用意されているので、N+1 問題の根本の原因は、以下にあると思っています。

  • 開発者が ORM の内部挙動を理解していない
  • ORM の利用方法が適切ではない

一方、今回「ぐるぐる SQL」と呼んだ問題は、条件分岐や複雑な条件の集計、例外処理、行間計算などを要する処理において、SQL 文で集合処理すれば良いところを、開発者がループを使って細かい SQL 文で明示的に逐次処理してしまうということを指しています。

こういった意見に対し、筆者はこのように回答しました。

@kanryu

N+1問題は英語ではそのまま N+1 Problem といい、SQLを始めとしたクエリ言語の運用で頻発する古典的な問題です。SQLに限らずGraphQLでだって発生します。

ORM運用時に表面化しやすいですがORMを使わなくても発生します。
また、集計していようがいまいが無関係で、ループ等で本来1回のクエリ呼び出しで完了するような処理をN回に分割して実行しているときは全てN+1として扱われます。

36
25
32

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
36
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?