はじめに
@abe_masanori さんが
- ぐるぐるSQLは止めてくださいという話
という記事を書かれたのですが、そこで「ぐるぐる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 文で明示的に逐次処理してしまうということを指しています。
こういった意見に対し、筆者はこのように回答しました。
N+1問題は英語ではそのまま N+1 Problem といい、SQLを始めとしたクエリ言語の運用で頻発する古典的な問題です。SQLに限らずGraphQLでだって発生します。
ORM運用時に表面化しやすいですがORMを使わなくても発生します。
また、集計していようがいまいが無関係で、ループ等で本来1回のクエリ呼び出しで完了するような処理をN回に分割して実行しているときは全てN+1として扱われます。
個人的にはselectに限らず「繰り返し部分でSQLを発行する実装」が問題ととらえていました。
("sql queries inside a loop"の記事は結構あるようです。)
https://www.google.com/search?q=using+sql+queries+inside+a+loop
ただこの覚え方だと、繰り返し部分のSQLの発行に限った問題としてしか覚えない可能性があるかと思います。
実際に私も
N + 1 Problem
について感覚として理解していても、レビュー時に本質を伝えることができていなかったと感じています。ご記載のように
N + 1 Problem
と理解し説明できたほうが良いと思うので勉強になりました。https://www.google.com/search?q=%22N+%2B+1+Problem%22
どっちの用語も見慣れなかった私なんかにしてみたら、
地域や世代によって同じ概念に別の用語があてられているのはしばしばあることなんだし、
そんな方言みたいなものにカリカリ怒らんでも、と感じました。
(英語圏でも、我々が知らないだけでN+1Problemを別のキャッチーな言葉で言い換えた表現が流通しているかもしれない)
まあ、こういう記事が書かれていけば、そのうち「ぐるぐるSQL」で検索した時に、
N+1問題も含めて検索してくれるようにGoogleさんが対応してくれるんじゃないでしょうか
ぐるぐるSQLは定着するでしょうか?
擬音が入るのは、いかにも日本人ですね!いや擬態語か。専門用語としては、些か幼稚な感じを受けます。オフィシャルな場では使いたくないです。バズワードとしても受け入れがたい。俗語ならまぁ。(個人の感想です)
ぐるぐるREST、ぐるぐるopen, close、ぐるぐるNoSQLもいけますかねw
言葉遊びとしては面白いから定着して欲しい気もするw
検索では明らかに「N+1問題」の方が優勢ですね。というより「ぐるぐる〜」の方は指数が0なので、一部の人だけが使っている呼称と言っても差し支えなさそうです。
Webエンジニアからすると「N+1」は誰でも知っているレベルの用語ですが、他分野の人からすると耳慣れなかったり、ORM以外の文脈で使うのは違和感があったりってことはあるのかもしれません。
日本人にわかりやすいように、初心者にもとっつきやすいように「ぐるぐるSQL」という言葉を選んで記事にしたことに対して、
それは一般的に、「N+1問題」という呼ぶんだよ、記事にその言葉も補足として追加しといてくださいとして指摘するのはわかります。
「ぐるぐるSQL」で記事にたどり着いた人が「N+1問題」というワードで新たに検索して、知識をつけていく。とても親切で素晴らしいことだと思います。
ただ、昔はそんな言葉を使っていなかったと新しい言葉を否定することは、ちょっと違うんじゃないかなと思いました。
日々言葉は変化していますし、今の若い子にとって、また初心者にとってわかりやすい言葉が生まれるなら、それは歓迎してあげるべきなんじゃないでしょうか。
プログラム初心者の私からすると、英語の記事を探す人の方が少数なのでは・・・?と勝手に思ってます。
「N+1」問題ともいわれてますね、と一言コメントを残すくらいでよいのでは?と個人的に思いました!
それでも労力をかけて反論記事をあげてまで伝えたい何かが、おそらくあるんですよね・・・
普段めったにコメントしませんが、なんか心が揺さぶられたので、思わずコメントしてしまいました。
@YottyPG
観点が違います。本件のような昔から存在する固有名称のある話題に対し、その固有名称を否定してオレオレ名称だけ書いている記事を元著者が書いてバズってしまったのが問題なのです。その記事だけを読んでわかったつもりになった人は、本来「N+1問題」と呼ばれていることを知らないままで終わってしまいます。そして英語のドキュメントに触れることもないのです。
@rudorufu1981
プログラミングの世界は英語でできています
プログラミングのドキュメント量が、日本語と英語で10倍以上違います。プログラミングの分野で英語資料を否定するのは、90%の情報を捨てているようなものです。
すごいストローマン論法だぁ…(恍惚)
@BlueRayi
本記事の主張の論点は
ぐるぐるSQL
という用語よりもN+1問題
という用語のほうがインターネット上で優勢であり他の記事を探しやすいN+1問題
という用語はN+1 Problem
の直訳であり、英語の記事も探しやすいであり、英語圏でどう扱われているかという話題も本質的なものです。
どこがストローマン論法なのか説明してください。
元の記事のどこに「N+1問題」を否定した記述があるのでしょうか?
私が読んだ限りでは「N+1問題」という言葉を使わず、詳しく説明していただけのように感じました。
ですので、「N+1問題」という言葉があることを執筆者にお伝えしてあげるだけでいいのではないでしょうか?
バズった記事に対して足りない情報があれば、その情報を補足してあげればいいだけだと思います。
はい、私も同意見です。
ですから、「N+1問題」という言葉があることを伝えて、記事に書き加えるように指摘するだけでいいと思います。
そうすれば、バズったことにより記事を読む人が増えて、「N+1問題」という言葉にも触れる人が増えて、いいことばかりだと思います。
「プログラム初心者の私からすると、英語の記事を探す人の方が少数なのでは・・・?」という文を、「プログラミングの分野で英語資料を否定」しているかのように歪めて引用し、その歪められた主張に対して反論しているようにみえた、ってことじゃないですか?(kanryuさん本人の主張に沿っているかではなく、相手の主張を歪めているかどうかです。)
これが、「たしかに、英語の記事を探す人は少ないでしょうね。プログラム初心者の方は特に。でも、プログラミングのドキュメント量が、日本語と英語で10倍以上違い、プログラミングの分野で英語資料を否定するのは、90%の情報を捨てているようなものなんです。だから優れた技術者は英語記事を検索していますし、技術記事を書くときは、英語圏でどう扱われているか、ということにも配慮するべきだと私は思っています。」みたいな書き方だったら、だれもストローマンだなんて言いません。
(N+1問題に加えてストローマンまでググってしまったよ。どんどん賢くなる…)
コメント欄で自分と違う意見に自社社員認定しようとしたりしたのが原因では・・・
過去のコメントを見ると攻撃的なコメントも多く見受けられるので、ぐるぐるSQL・N+1問題論争以前にネットリテラシーの問題な気もします。
@jinoji
補足ありがとうございます。勉強になります。
しかしながら、技術的な議論をするときはそれぞれ結論、補足説明の順で書くべきであって、補足いただいた内容は普通誰でもわかるじゃん、って思ってしまうんですがダメなんでしょうかね。
@Reframe
自分と違う意見だったからでなく、元記事作者含めて3人とも同じユーザーアイコンだったので同じ会社の人間と見なしたのが原因でした。まさかありものアイコンを貼り付けたまま他の人とかぶっているのに放置するなんて紛らわしい運用をしてる人が居るなんて思いもしませんでした。
攻撃的なコメントになるのは自分の性格的なものもあるので、ある程度は仕方ないかなと思っています。
攻撃的なコメントが書かれるのはその技術記事にとってマイナスの作用があります。
性格的なものだと自覚があるなら尚更、コメントを書く際によく留意してほしいです。
プログラミングも、技術記事やコメントも、広く言えば「言葉」ですが、
前者は機械に対しての命令であるのに対して、後者はヒトに伝えるためのものです。
心を持つ相手に伝えるためのワードチョイスには、もっと気を配ってほしいと思います。
@jinoji
どうもありがとうございます。おっしゃる通りですね。
私の現状の筆力では
みたいなこなれた表現をいきなりひねり出すのは無理そうなんですが、なにかいい書き方の資料とかはありませんでしょうか。
@POPOPON
検索頻度の調査はとても有意義だと思います。
私も試してみたんですが、「N-1問題」がヒットしてくるのがちょっと引っかかってます。
キーワード内に記号が含まれているとよく分からない挙動をしますね。
ちなみに、「N+1問題」と「N-1問題」の比較結果はほぼ同じです
とはいえ、私も「N+1問題」の方がメジャーなんだろうなぁと認識しています。
@kanryu
「まさかありものアイコンを貼り付けたまま他の人とかぶっているのに放置するなんて紛らわしい運用をしてる人が居るなんて思いもしませんでした。」
もなかなか失礼な言い方だと思います。
デフォルトアイコンで有意義な活動をされている方、沢山いらっしゃると思いますよ!
(居るなんて思いもしないなんて言われると、逆に変えにくくなってしまいました)
私は@kanryuさんのコメントで色々勉強になったので感謝しています。自分の技術不足を痛感しました。
既に指摘されていますが、攻撃的なコメントは本当にもったいないと思います。
良い指摘や提案でも、攻撃的であることを理由に全く関係ない議論が始まるのは、コミュニティ全体への損失に繋がると思います。Qiitaに限らずネット上でよく見かけます。
@jinojiさんから色々指摘されている中で、同じようなことを連投するようで申し訳ないですが、攻撃的なコメントをされた側としてコメントさせて頂きました。
そして、私も火に油を注ぐようなコメントをついしてしまいがちなので、気をつけたいと思います。
私自身の言葉遣いは、何かを読んで身につけたというより、長い間かけて自然に身についたように思います。なので、具体的な資料をご紹介することはできません。すみません。
あ、ひとつだけ思いついたので書いておくと、私がこのひとつ前のコメントを書いたときに、「IメッセージとYOUメッセージ」という話を思い出して、少しだけ文章を修正しました。(修正前は「留意してください」と書いていた)
ただ、むしろ@kanryuさんが、いつかそういう「いい書き方」のための資料を作ると良いのではないかと思いました。
今後も「妙に反発を受けた」と感じることはあるでしょうから、その時に、(相手に反論する前に、)自分の文章のどこが読み手を逆なでしたのか、何が余計だったのか、どう言い換えれば良かったのか、と考える習慣をつければ、いつか、同じような性格を持つ人の助けになるノウハウ集が出来上がるかもしれません。
これはデフォルトアイコンですね。
仕方ないで済ませて攻撃的なコメントをし続けた結果が今の状況だと思います。
一度自分のしてきたコメントを見返して、「仕方ない」で終わらないと思える事を願います。
余談ですが、この記事は技術的な記事ではないと思いますので、タグを適切なもの(ポエムになっちゃうのかな・・・)に変えるといいと思います。
@kanryu
@jinoji
ありがとうございます!
英語のドキュメントはこれまでずっと避けてきたので、これを機に頑張って英語記事も少しずつ読んで慣れていこうと思います!
@kanryu
非常におこがましいですが、個人的な一意見だけ・・・
アドラー心理学では、課題の分離という考えがあり、名著『嫌われる勇気』の中では、
というのがあります。ロバが水を飲むのかどうか、はロバの課題であり、ロバを水辺に連れて行く人が強制するものではないという考えです。
何がいいたいかといいますと、
相手の考えが100%間違っていると思う場合でも、相手が意見を変えるかどうか(「ぐるぐるSQLという用語を使用するのをやめるかどうか」)は相手側の課題であり、強制するものではないということです。
それでも説得したい場合、
できることは自分の考えとその根拠を相手のレベルに合わせて丁寧に伝えることだけであり、
相手が考えを改めるかどうかは相手に委ねる、というスタンスです。
(@jinojiさんの英語記事の件のコメントはまさに上記の通りの文章になっていると思います!)
このスタンスをとると、自然と@jinojiさんのような文章になるのかな?と思いました。
※攻撃的・相手の考えの一方的に否定をしては、相手の考えを改める確率はより下がると私は思いました。
と長々書き込んでしまいましたが、人それぞれ性格も違いますし、
課題の分離という考えを強制したいわけではないです!
あくまで一意見としてコメント残させていただきます。
別に造語自体は好きじゃないんですが、Qiita読むのはほぼ日本人でしょうし、タイトル見て「おっなんだこの記事」って思わせてクリックさせれたなら、読ませるための導入のタイトルとしては成功しているのではないでしょうか。元々の問題を知らないならN+1 Problemで検索してわざわざ読まないでしょうし、記事とついているコメント読んでN+1 Problemというものを一人でも多く知ったのであれば、それはそれで良い事だと思います。
提案はある程度の人は許容してくれますが、否定は正しくても何だコイツって思う人は出ますし、場合によっては禍根を残す場合もあります。相手が受け入れやすいワードチョイスをするのも、一種の技術だと思います。
ただ、それを気にしない、受け入れない奴はこちらからお断りだという生き方なら、別にそれはそれで良いと思います。
@lux2031
多分、形態素解析で文字種別(アルファベット、記号、数字とか)語句が分解されているので"N - 1問題"は"N" "-" "1" "問題"のフレーズでも検索されているんだと思います。(実際の分解はこんな単純なモノじゃないと思いますが)。"N+1問題"は用語として定着してるので辞書に登録があるんだと思います。
また、N-1問題は経済学の為替に関する用語であるのでノイズが乗るかも知れません。数学の問題文で「問題1、、、(n+1)」とかでもノイズが乗るかも知れないのでカテゴリで「プログラミング」で絞った方が良いかもしれません。今回は結果はたいして変わりませんが。
失礼しました
と書いた後に気づきました。Trendは検索語の分析でしたね。なので数学の問題のノイズは乗って来ませんね。通常のsearchと勘違いしました。でもカテゴリーは指定した方が良いかも知れません。
度々失礼しました。
更に追加w
トレンドで調べるのもなんか違う気がしたので通常の検索で検索軒数調べて見ました。
N+1問題 で言語と地域を日本、語順も含めて完全一致で検索。
7180件 ただしやはり記号が含まてるので、N 1 問題 で分解され、N-1とか数学の問題のノイズが乗ってくる。
ぐるぐるSQL で言語と地域を日本、語順も含めて完全一致
1040件
ぐるぐる系SQL 条件は上に同じ
40件
グルグルSQL 条件は上におなじ
一致なし。
結果、
ノイズありN+1問題 7180件
ぐるぐるSQL, ぐるぐる系SQL 1080件
そんなに圧倒的な差があるわけでは無さそう。
N+1問題はどうしてもノイズが取り除けないw
度々たび失礼しました
一見大人に見える人間の幼児性と攻撃性をあぶりだす良記事ですね。本件、狭いコミュニティのローカルスラングを使っていた不明を恥じる案件ですよ。認めずスラングの妥当性を主張し相手が悪いとまくしたてる。まるで政権批判に噛みつくネトウヨを見るようで、日本の闇と業深き戦後教育の失敗の開花を見るようです。
コロナが蔓延しても、仕方ないからとあきらめる人が多いのも納得ですよ。
@souchi00
ありがとうございます。ノイズ取り除けないんですよねー。
ぐるぐるSQLの方も気になっている所はあって、
この記事で紹介されている最古のツイート「ぐるぐるSQL回すしか手はない」も、
「ぐるぐる(と)SQL(を)回すしか手はない」ってただ書きなぐっているだけで、
「ぐるぐるSQL」という用語を意識して使ってないんじゃないかなぁ…とか思ったり。
こういうノイズを取り除くには、
「WYSIWYG」みたいに絶対に他とは被らない用語が良いのかもしれませんね。(笑)
N件のデータを受け取って、N回のループでSELECTとかしつつループの最後で1件ずつINSERTするという問題は、N+1問題ではしっくりこず、むしろぐるぐるSQLの方がしっくりきます。
(N+1問題について解説する際に、)ぐるぐるSQLという用語(をN+1問題という用語の存在を教えずに使用するの)は止めてくださいという話