クエリとは?SQLとの違い・種類・実行の仕組みと高速化を実装目線で解説
クエリとは、データベースに対して「このデータを取り出したい」「この行を書き換えたい」と伝える問い合わせ・命令文のことです。アプリケーションが画面に一覧を出すときも、集計レポートを作るときも、裏では必ずクエリがデータベースへ飛んでいます。クエリを読み書きできると、どんなデータがどう取れるのかを自分で確かめられ、動作が遅い・想定と違う結果が返る、といった不具合の原因にも手が届くようになるはずです。この記事では、クエリの意味とSQLとの違いから、データを取り出す検索クエリとデータを変える操作クエリの種類、クエリがパースされ実行される仕組み、実行計画やスロークエリを手がかりに遅いクエリを速くするチューニング、プレースホルダでSQLインジェクションを防ぐ安全な書き方、そして生のSQLとORMとBIツールをどう使い分けるかまでを、実装の現場視点で整理します。
目次
まとめ:クエリの意味・種類とデータベース操作での役割
クエリの芯は、データベース管理システム(DBMS)に向けて「何を、どういう条件で、どうしたいか」を文で伝えることにあります。英語の query は「問い合わせ」「質問」という意味で、その名のとおり、人がキーボードで検索窓に打ち込むのではなく、プログラムがデータベースへ投げる一件の要求のことです。多くの場合、この要求はSQLという言語で書かれ、「SELECT(取り出す)」「INSERT(追加する)」「UPDATE(変える)」「DELETE(消す)」といった動詞で始まる一文になります。
クエリは、目的で大きく二つに分かれます。ひとつは、条件に合うデータを読み出すだけの検索クエリ(SELECT)で、データそのものは変えません。もうひとつは、データを追加・変更・削除する操作クエリで、実行するとデータベースの中身が書き換わります。読むだけなのか、書き換えるのかを意識して区別することが、事故を防ぐ第一歩です。投げたクエリは、DBMSがいったん解釈し、どう取りにいくかの段取り(実行計画)を組み立ててから実行するため、同じ結果でも書き方しだいで速さが大きく変わります。
クエリが効いてくるのは、大量のデータから必要な一部だけを、条件を付けて素早く取り出したい場面です。逆に、扱うデータが数件で構造も単純なら、クエリの書き方に神経を使う必要はありません。どこまでチューニングに手をかけ、どこで割り切るか、その線引きまで条件付きで言い切ります。クエリを書く言語であるSQLそのものの文法はSQLとは何かで、クエリを投げる先のデータベースの全体像はデータベースとは何かで扱い、本記事はその中間にある「問い合わせ文としてのクエリ」をどう実行し、どう速く安全に書くかを担います。
クエリとは何か:データベースへの問い合わせ・命令文としての定義
はじめに言葉の範囲をそろえます。クエリという語は、データベースの文脈とWeb検索の文脈で少しずつ意味がずれて使われるため、まずどれを指しているのかを切り分けておくと、後の話が混ざりません。
クエリの定義と、「問い合わせ」という言葉が指すデータへの要求
クエリ(query)は、データベースやソフトウェアに対して、データの取得や処理を求める要求を指します。語源は「問い合わせる」「尋ねる」という英単語で、まさに「このデータをください」「この値に更新してください」とシステムへ問いかける一文だと考えると分かりやすいです。実務でクエリと言えば、ほとんどの場合はリレーショナルデータベースへ投げるSQLの文を指します。たとえば「注文テーブルから、今日の分だけ、金額の大きい順で取り出す」という要求を一文で書いたものが、ひとつのクエリです。人が対話的に打つこともあれば、アプリケーションのコードが自動で組み立てて送ることもあり、どちらもデータベースから見れば同じ一件の問い合わせとして届きます。
SQLとクエリの違い:言語そのものと、その言語で書いた一件の問い合わせ
混同しやすいのが、SQLとクエリの関係です。SQLは、データベースを操作するための言語そのものを指し、クエリは、そのSQLで書かれた一文(問い合わせ)を指します。英語という言語と、英語で書かれた一つの文章の関係に近いと考えると整理できます。たとえば SELECT * FROM users WHERE age >= 30; は、SQLという言語で書かれた、ひとつのクエリです。ですから「SQLを使ってクエリを書く」という言い方が正確で、両者は対立する別物ではなく、言語と、その言語での一文という包含の関係にあります。SQLにはデータを操作するDML(SELECT/INSERT/UPDATE/DELETE)のほか、テーブルを定義するDDL、権限を扱うDCLなどの区分があり、日常的に「クエリ」と呼ぶのは主にデータを読み書きするDMLの文です。言語としてのSQLの区分や実行順序を深掘りしたい場合は、SQLとは何かを土台にすると、本記事のクエリの話がつながります。
検索クエリ・URLのクエリ文字列との違いで言葉の範囲を切り分ける
クエリという言葉は、データベース以外でも使われます。まぎらわしいものは三つです。ひとつは、検索エンジンにユーザーが入力する語句を指す「検索クエリ」で、SEOやWeb解析の文脈で登場します。もうひとつは、URLの末尾に ?keyword=database&page=2 のように付く「クエリ文字列(クエリパラメータ)」で、リクエストに条件を渡すための記法です。これらは、データベースへ命令文を送るデータベースクエリとは別物です。本記事が扱うのは、DBMSへ投げるデータベースクエリで、以降でクエリと書くときはこの意味を指します。同じ「クエリ」でも、検索窓の入力語なのか、URLのパラメータなのか、データベースへの命令文なのかで話が変わる点を、最初に押さえておくと混乱しません。
クエリの種類:検索(SELECT)と操作(INSERT・UPDATE・DELETE)
クエリは、データを読むだけか、書き換えるかで性格が大きく違います。ここを取り違えると、意図せずデータを消してしまう事故につながるため、種類ごとの役割を分けて押さえます。
データを取り出す検索クエリ(SELECT)の基本構造と絞り込みの書き方
もっとも使うのが、条件に合うデータを読み出す検索クエリで、SELECT文がこれにあたります。基本の形は、取り出す列を SELECT で、対象のテーブルを FROM で、絞り込みの条件を WHERE で指定する三点セットです。たとえば SELECT id, name FROM customers WHERE age >= 30; は、顧客テーブルから30歳以上の行だけを、IDと名前の二列に絞って取り出す問い合わせです。ここに、並べ替えの ORDER BY、件数を絞る LIMIT、複数テーブルをつなぐ JOIN、集計する GROUP BY を足していくと、表現できる問い合わせが一気に広がります。検索クエリの利点は、元のデータを一切変えずに、見たい切り口だけを何度でも取り出せる点です。まず読み取りのクエリで対象データを正確に絞り込めるようになることが、次の操作クエリを安全に扱う前提になります。
データを変える操作クエリ(INSERT・UPDATE・DELETE)と扱う際の注意
データベースの中身を書き換えるのが操作クエリで、行を追加する INSERT、既存の行を変更する UPDATE、行を消す DELETE があります。これらは実行するとデータが実際に変わるため、検索クエリより慎重さの要る操作です。とくに危ないのが、WHERE を付け忘れた UPDATE や DELETE で、条件がなければテーブルの全行が書き換え・削除の対象になります。実務では、まず同じ条件のSELECTで対象行を確かめてから操作クエリに書き換える、更新は一連の処理をトランザクションでまとめて途中失敗時にまとめて取り消せるようにする、といった作法が事故を防ぐ備えです。同じ行を複数の処理が同時に更新しようとすると、後勝ちでデータが上書きされたり待ちが発生したりするため、更新クエリを扱う場面では排他制御の考え方が要ります。この同時更新の制御は楽観ロックと悲観ロックで詳しく扱っており、更新クエリの設計と地続きです。
クエリが解釈・実行される仕組み(パース→オプティマイザ→実行)
投げたクエリは、そのまま順番に処理されるわけではありません。DBMSは受け取ったクエリを、おおむね三段階で処理します。まず構文を解析して意味を取る「パース」、次に、どのインデックスを使い、どういう順でテーブルを読むかの段取りを組み立てる「クエリオプティマイザ(実行計画の生成)」、最後にその計画に沿ってデータを取りにいく「実行」です。ここで鍵になるのが二段階目で、同じ結果を返すクエリでも、オプティマイザが選ぶ段取りしだいで、全件を舐めるか、索引を使って必要な行へ一足飛びに届くかが変わり、速さが桁で違ってきます。この「クエリを解釈して実行する頭脳」がDBMSであり、製品ごとにオプティマイザの賢さや使えるインデックスの種類には差があるのが実情です。どのDBMSを選ぶかでクエリの書き味や性能が変わる点はDBMSとは何かで整理しています。クエリを書く側は、DBMSがどう段取りを組むかを意識すると、なぜこのクエリが遅いのかを説明できるようになります。
クエリを速く・安全に書くための実装判断と、内製が難しいときの体制
ここからは立場を明確にします。クエリは、動けばよいというものではなく、遅いクエリや危険なクエリはシステム全体の足を引っ張る厄介な存在です。どこに手をかけるべきか、その判断基準を具体的な条件で示します。
実行計画(EXPLAIN)とスロークエリから遅いクエリを直す判断
クエリが遅いとき、勘で書き直す前に、DBMSが組んだ段取りを見るのが近道です。多くのRDBMSは、クエリの前に EXPLAIN を付けると実行計画を返し、どのインデックスを使うか、何行を読む見込みか、テーブルを全件走査していないかを確認できます。全件走査(フルスキャン)が出ていて対象が大きいなら、WHERE や JOIN で絞り込む列にインデックスを足すのが第一手です。あわせて、一定時間を超えたクエリを記録するスロークエリログを有効にしておくと、本番で実際に遅い問い合わせを事実ベースで拾えます。判断の順序は、スロークエリログで遅い問い合わせを特定し、EXPLAINで段取りを読み、インデックス追加やクエリの書き換えで直す、という流れが手戻りが少ないです。ここで注意したいのは、索引を増やすほど検索は速くなる一方、追加・更新のたびに索引の維持コストがかかる点で、読み取りと書き込みのどちらが多い処理かを見て、かける手を決めます。この読み書きの比率を踏まえた設計は、性能を左右する判断の一つです。
プレースホルダ(パラメータ化クエリ)でSQLインジェクションを防ぐ
クエリの安全性で最初に押さえるべきが、SQLインジェクションへの備えです。これは、ユーザーが入力した値を、文字列としてそのままクエリに連結してしまうと、攻撃者が入力欄にSQLの断片を混ぜ込み、意図しないデータの読み出しや削除を実行できてしまう脆弱性です。防ぎ方は明快で、値を文字列連結でクエリに埋め込むのをやめ、プレースホルダ(パラメータ化クエリ、プリペアドステートメント)を使うことに尽きます。WHERE id = ? のように値の場所を記号で空けておき、実際の値はデータベースドライバに別枠で渡すと、渡した値は必ずデータとして扱われ、SQLの命令としては解釈されません。フレームワークやORMを使っていれば、この仕組みが既定で働くことが多いものの、生のSQLを文字列で組み立てる箇所には抜けが残りがちです。ユーザー入力が関わるクエリは、例外なくプレースホルダで組む、という原則を徹底することが、実装での最低ラインになります。
生SQL・ORM・BIツールを使い分ける判断と、受託でのクエリ設計体制
クエリを書く手段は、生のSQLだけではありません。目的に応じて三つを使い分けます。生SQLは、複雑な結合や集計、性能を詰めたい処理で、DBMSの機能をそのまま引き出せるのが強みで、チューニングの効きも読みやすいです。ORM(オブジェクト関係マッピング)は、アプリケーションのコードからメソッドの組み合わせでクエリを組み立てる仕組みで、単純なCRUD(作成・参照・更新・削除)を素早く安全に書けますが、生成されるクエリが見えにくく、意図せず遅いクエリを量産することもあります。BIツールは、SQLを直接書かずに画面操作で集計・可視化する用途に向き、非エンジニアがデータを見る場面で力を発揮します。判断の目安は、日常的なアプリのデータ操作はORMで書きつつ、性能が問われる箇所や複雑な集計だけ生SQLに落とし、分析・レポートはBIに寄せる、という組み合わせが現実的です。とはいえ、大量データを扱う業務システムでは、クエリの設計とチューニングが性能と安定性を左右し、これはインデックス設計やDBMSの癖まで含めた専門知識が要る仕事です。社内にクエリの性能まで見られる人材がいない、既存システムのクエリが遅くて改修に踏み切れない、といった場面では、外部の伴走が歯止めになります。一創では基幹システム開発として、業務要件をデータモデルへ落とす設計から、クエリの設計・チューニング、運用までを一貫して支援しています。動くクエリを書くだけでなく、増えるデータに耐えるクエリと索引を業務要求から導くところまで含めた伴走が一創の強みです。
よくある質問
クエリの理解と実務でつまずきやすい点を、5つの質問に絞って整理します。
クエリとSQLは何が違いますか?
言語と、その言語で書いた一文の関係です。SQLは、データベースを操作するための言語そのものを指し、クエリは、そのSQLで書かれた一件の問い合わせ(命令文)を指します。SELECT * FROM users; は、SQLで書かれたひとつのクエリ、という関係です。ですから両者は対立する別物ではなく、「SQLを使ってクエリを書く」という包含の関係にあります。日常会話では厳密に区別せず両方をクエリと呼ぶこともありますが、言語の話をしているのか、投げる一文の話をしているのかを意識すると、設計の議論が正確になります。
検索クエリとデータベースのクエリは同じものですか?
別物です。検索クエリは、GoogleなどのWeb検索でユーザーが入力する語句を指し、SEOやアクセス解析の文脈で使われます。データベースのクエリは、DBMSに対してデータの取得や更新を求める命令文のことです。名前は同じ「クエリ」でも、前者は検索窓への入力語、後者はデータベースへのSQL文で、対象も仕組みも異なります。加えて、URLに付く ?key=value 形式のクエリ文字列も別の意味なので、どの文脈で使われているかを見て取り違えないようにします。
クエリが遅いとき、まず何を見ればよいですか?
実行計画を確認します。クエリの前に EXPLAIN を付けて、どのインデックスを使うか、テーブルを全件走査していないか、何行を読む見込みかを読みます。全件走査が出ていて対象データが大きい場合は、絞り込みや結合に使う列へインデックスを足すのが第一手です。本番で遅い問い合わせを事実ベースで拾うには、スロークエリログを有効にしておくと、実際に時間のかかっているクエリを特定できます。スロークエリログで遅いものを見つけ、EXPLAINで段取りを読み、索引追加や書き換えで直す、という順で進めると手戻りが減ります。
SQLインジェクションはどう防げばよいですか?
プレースホルダ(パラメータ化クエリ)を使います。ユーザー入力を文字列としてそのままクエリに連結すると、入力欄にSQLの断片を混ぜ込まれ、意図しない操作を実行される危険があります。WHERE id = ? のように値の位置を記号で空けておき、実際の値はデータベースドライバへ別枠で渡すと、その値は必ずデータとして扱われ、命令としては解釈されません。多くのフレームワークやORMは既定でこの仕組みを使いますが、生のSQLを文字列で組む箇所は抜けやすいため、ユーザー入力が関わるクエリは例外なくプレースホルダで組む、と徹底します。
クエリはSQLの知識がないと書けませんか?
手段によります。生のクエリを書くにはSQLの基本文法(SELECT・WHERE・JOINなど)の理解が要りますが、ORMを使えばプログラムのコードからメソッドの組み合わせで単純なクエリを組み立てられ、SQLを直接書く場面を減らせるのが利点です。集計や可視化だけが目的なら、BIツールで画面操作からクエリを組む方法もあり、SQLをほとんど書かずに済みます。ただし、性能が問われる複雑な処理では、生成されたクエリの善し悪しを判断するためにSQLの理解が要るため、まずSELECTでデータを正確に絞り込む練習から始めると土台ができます。
関連記事
- SQLとは:クエリを書く言語そのもの。DDL・DML・DCLの区分と実行順序、RDBMS方言の書き分け
- データベースとは:クエリを投げる先のDBの種類・DBMS・RDBとNoSQLの選び方の全体像
- DBMSとは:クエリを解釈して段取りを組み実行するエンジン。製品ごとの機能と選び方
- 楽観ロックと悲観ロックとは:更新クエリが同時に走るときの排他制御。後勝ち更新を防ぐ設計
- データレイクとは:大規模データにクエリを投げる分析基盤。DWH・レイクハウスとの違い