データベースSQL SELECTクエリの仕組み

データベースSQL SELECTクエリの仕組み

私たちは Web 開発者として、プロの DBA ではありませんが、データベースなしではやっていけません。ほとんどの開発者は、select、insert、delete、update という 4 つの標準的な SQL ステートメントの使い方しか知りません。これまで、select がどのように動作するかを学んだことがなかったので、ここでは、select がデータベース内でどのように動作するかについて説明します。

B/S アーキテクチャで最も古典的なトピックは 3 層アーキテクチャであり、これは大まかにデータ層、ビジネス ロジック層、プレゼンテーション層に分けられます。データ層の機能は、一般的にレコードのクエリなど、データベースと対話することです。多くの場合、クエリ SQL を記述してから、プログラムを呼び出して SQL を実行します。しかし、その内部ワークフローはどのようなものでしょうか?私の友人のほとんども、私と同じように、最初にどのステップを踏めばいいのか、次にどのステップを踏めばいいのかわからないと思います。

ステップ1: アプリケーションはクエリSQL文をサーバーに送信して実行します。

データ層で SQL ステートメントを実行すると、アプリケーションは対応するデータベース サーバーに接続し、SQL ステートメントをサーバーに送信して処理します。

ステップ2: サーバーは要求されたSQL文を解析します

1. SQL プラン キャッシュ。クエリ アナライザーをよく使用する友人は、おそらくこのような事実を知っているでしょう。多くの場合、クエリ ステートメントは、初めて実行するときに実行に非常に長い時間がかかりますが、同じステートメントをすぐに実行するか、特定の期間内に実行すると、クエリ結果が非常に短い時間で返されます。

理由:

  • クエリ要求を受信した後、サーバーはすぐにデータベースをクエリするのではなく、データベースのプラン キャッシュを調べて、対応する実行プランがあるかどうかを確認します。存在する場合は、コンパイルされた実行プランを直接呼び出すため、実行プランのコンパイル時間が節約されます。
  • クエリ対象の行がデータ バッファー ストレージ領域にすでに存在する場合、物理ファイルをクエリする必要はありません。代わりに、データはキャッシュから取得されます。この方法では、メモリからデータを取得する方がハード ディスクからデータを読み取るよりもはるかに高速であるため、クエリの効率が向上します。データ バッファー ストレージ領域については後で説明します。

2. SQL プラン キャッシュ内に対応する実行プランがない場合、サーバーはまずユーザーが要求した SQL ステートメントの構文検証を実行します。構文エラーがある場合、サーバーはクエリ操作を終了し、呼び出し元のアプリケーションに対応するエラー メッセージを返します。

注意: この時点で返されるエラー メッセージには、select が selec として記述されているなど、基本的な構文エラー情報のみが含まれます。エラー メッセージにテーブルに存在しない列が含まれている場合、これは構文の検証のみであるため、サーバーはこの時点でそれをチェックしません。セマンティクスが正しいかどうかは、次の手順で処理されます。

3. 構文が適合したら、テーブル名、列名、ストアド プロシージャ、その他のデータベース オブジェクトが実際に存在するかどうかなど、セマンティクスが正しいかどうかの検証を開始します。存在しないオブジェクトが見つかった場合は、アプリケーションにエラーが報告され、クエリが終了します。

4. 次のステップは、オブジェクトの解析ロックを取得することです。テーブルをクエリすると、サーバーは最初にオブジェクトをロックして、データの一貫性を確保します。ロックされていない場合は、この時点でデータが挿入されますが、ロックがないため、クエリはレコードを読み取ってしまい、トランザクションの失敗により一部の挿入がロールバックされ、ダーティリードが発生します。

5. 次のステップは、データベース ユーザーの権限を確認することです。SQL ステートメントの構文とセマンティクスが正しい場合でも、この時点ではクエリ結果が取得されない場合があります。データベース ユーザーが対応するアクセス権を持っていない場合、サーバーはアプリケーションに権限不足エラーを報告します。大規模なプロジェクトでは、プロジェクト内に複数のデータベース接続文字列が存在することがよくあります。これらのデータベース ユーザーにはさまざまな権限があり、読み取り専用権限、書き込み専用権限、読み取りと書き込みが可能な権限があります。異なる操作に応じて、異なるユーザーが実行するように選択されます。注意しないと、SQL ステートメントがどれだけ完璧であっても役に立たなくなります。

6. 分析の最後のステップは、最終的な実行計画を決定することです。構文、セマンティクス、権限が検証された後、サーバーはすぐに結果を返すのではなく、SQL を最適化し、さまざまなクエリ アルゴリズムを選択して、最も効率的な形式で結果をアプリケーションに返します。たとえば、テーブル結合クエリを実行する場合、サーバーは最終的にコスト、どのインデックスがより効率的かなどに基づいて、ハッシュ結合、マージ結合、またはループ結合のどれを使用するかを決定します。ただし、自動最適化には制限があります。効率的なクエリ SQL を記述する場合は、SQL クエリ ステートメントを最適化する必要があります。

実行プランが決定されると、SQL プラン キャッシュに保存されます。次に同じ実行要求があった場合、実行プランの再コンパイルを回避するために、プラン キャッシュから直接取得されます。

ステップ3: ステートメントの実行

サーバーは SQL ステートメントの解析を完了すると、ステートメントの実際の意味を認識し、実際に SQL ステートメントを実行します。

現時点では 2 つの状況があります。

  • クエリ ステートメントに含まれるデータ行がデータ バッファー ストレージ領域に読み込まれている場合、サーバーはデータ バッファー ストレージ領域からデータを直接読み取り、アプリケーションに返します。これにより、物理ファイルからの読み取りが回避され、クエリ速度が向上します。
  • データ行がデータ バッファー ストレージ領域にない場合は、レコードが物理ファイルから読み取られてアプリケーションに返され、データ行は次回の使用のためにデータ バッファー ストレージ領域に書き込まれます。

注: SQL キャッシュにはいくつかの種類があります。興味のある方は、ここで検索できます。キャッシュの存在により、最適化の結果をすぐに確認することが難しい場合があります。キャッシュの存在により 2 回目の実行が非常に高速になるため、通常は最初にキャッシュを削除してから、最適化の前後のパフォーマンスを比較します。一般的な方法をいくつか示します。

DBCC DROPCLEANBUFFERS

バッファ プールからすべてのクリア バッファを削除します。

DBCC FREEPROCCACHE

プロシージャ キャッシュからすべての要素を削除します。

DBCC FREESYSTEMCACHE

すべてのキャッシュから未使用のキャッシュ エントリをすべて解放します。

SQL Server 2005 データベース エンジンは、現在のエントリにメモリを使用できるようにするために、未使用のキャッシュ エントリを事前にバックグラウンドでクリーンアップします。ただし、このコマンドを使用して、すべてのキャッシュから未使用のエントリを手動で削除することができます。

これは基本的にSQLキャッシュの影響を排除することしかできません。キャッシュを完全に排除する解決策はないようです。もし何かあれば教えてください。

結論: アプリケーションによって送信された SQL を実行するサービスの操作プロセスを知ることによってのみ、アプリケーションを適切にデバッグできます。

  • SQL 構文が正しいことを確認してください。
  • SQL のセマンティックの正確性、つまりオブジェクトが存在するかどうかを確認します。
  • データベース ユーザーが対応するアクセス権を持っているかどうか。

要約する

以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。これについてもっと知りたい場合は、次のリンクをご覧ください。

以下もご興味があるかもしれません:
  • MySQL マスター/スレーブ データベース同期構成と一般的なエラー
  • PHP シングルトン モード データベース接続クラスとページ静的実装メソッド
  • データベースの水平セグメンテーションを実装するための2つのアイデア
  • MySQL データベースの大文字と小文字の区別の問題
  • Pythonはadbapiを使用してMySQLデータベースの非同期ストレージを実装します
  • データベースフィールド設計の経験について話す
  • MySQLデータベースのストアドプロシージャとトランザクションの違い
  • MySQLデータベースのQPSとTPSの意味と計算方法
  • MySQLデータベースが大きすぎる場合にバックアップと復元を行う方法
  • データベースの冗長フィールドを合理的に使用する方法

<<:  Dockerコンテナのホスト間通信におけるダイレクトルーティングの詳細な説明

>>:  Vueカスタムテーブル列実装プロセス記録

推薦する

Keras を使って SQL インジェクション攻撃を判断する (例の説明)

この記事では、ディープラーニングフレームワーク keras を使用して、SQL インジェクションの特...

MySQL エラー: 接続数が多すぎる場合の解決策

MySQLデータベースの接続が多すぎますこのエラーは明らかに、mysql_connect の後に m...

モバイル開発チュートリアル: ピクセル表示の問題の概要

序文モバイル端末の開発の過程で、モバイル端末のディスプレイはデスクトップ端末のディスプレイとは一般的...

フォームを送信した後、別のファイルに移動する

<br />質問:特定のファイルにジャンプするには、HTML でどのように記述すればよい...

HTML埋め込みタグの使用方法と属性の詳細な説明

1. 基本的な文法コードをコピーコードは次のとおりです。埋め込み src=url注: 埋め込みはさま...

DOCTYPE HTMLを使用する理由

これがないと、ブラウザはページをレンダリングするときに Quirks モードを使用することがわかって...

Mysql の大きな SQL ファイルの高速リカバリ ソリューションの共有

序文MySQL データベースを使用する過程では、データベースのバックアップと復元が必要になることがよ...

Linuxコマンドunzipの詳しい説明

目次1. 解凍コマンド1.1 構文1.2 オプション2. 例1. 解凍コマンドunzip コマンドは...

CSS3 で実装された画像ホバートグルボタン

結果:実装コードhtml <ul class="スライド"> <...

Echarts は 1 つのグラフ内で異なる X 軸を切り替える機能を実装します (サンプル コード)

レンダリング下の画像のような効果を実現したい場合は、読み続けてアニメーション画像に直接進んでください...

MySQL DEFINER の使用方法の詳細な説明

目次序文: 1.DEFINERの簡単な紹介2. いくつかの注意点要約:序文: MySQL データベー...

2つのNode.jsプロセスがどのように通信するかの詳細な説明

目次序文異なるコンピュータ上の 2 つの Node.js プロセス間の通信TCPソケットの使用HTT...

Ubuntu 20.04でルートアカウントを有効にする方法

Ubuntu 20.04 をインストールした後、デフォルトでは root アカウントのログイン権限が...

Web フロントエンドのパフォーマンス最適化の詳細説明: リソースのマージと圧縮

2つの目的のためのリソースの結合と圧縮httpリクエストの数を減らす要求されたリソースのサイズを縮小...

CSS3 を使用して左上または右上隅にリマインダー ドットを表示するサンプル コード

効果画像(三角形をご希望の場合は、ここをクリックしてください): コード: <html>...