基礎から理解するデータベースのしくみ(2)SQL文はどのように実行されるのか(1)
初公開日:2006/01/18
SQL文を記述してデータベースを操作することはそれほど難しいことではありません。しかし,リレーショナル・データベース管理システム(RDBMS)が問い合わせを実行する速度は,SQL文の書き方によって大きく異なります。ちょっとした記述の違いによって,応答時間が何倍も違うことはめずらしくありません。 では,速いSQL文を書けるようになるためには,どうすればいいのでしょうか。その答えは,「RDBMSがSQL文を内部でどのように処理しているのか」を理解することです。RDBMSは,プログラマが記述したSQL文を基にさまざまな処理を行ってから実際にデータベースにアクセスします。その過程を知ることで,アクセスのしかたをコントロールできるようになるのです。 例えば,CUSTOMERS(顧客)テーブルからNAME(名前)を抽出する「SELECT NAME FROM CUSTOMERS」という簡単なSQL文であっても,RDBMS内部ではさまざまな処理を経て結果を返します。こうした仕組みを理解することで,ただ結果を求めるだけのSQL文を書くのではなく,「目的に応じて適切なSQL文を書く」という発想が生まれてくるのではないかと思います。 Part1では,RDBMSがSQL文を内部でどのように処理しているのかを,最適化の話を中心に解説します。あわせて,速いSQL文を書くためのポイントも紹介しましょう。アプリケーション開発やデータベース設計など,さまざまな場面で活用していただけたら幸いです。 SQL文は実行までに三つの過程を経る最初に,RDBMSがSQL文をアプリケーションから受け取ってから実行するまでの流れを眺めてみましょう。大きく,(1)SQL文の解析,(2)SQL文の書き換え,(3)実行計画の作成,の三つの処理過程があります(図1[拡大表示])。順に説明していきましょう。 (1)SQL文の解析RDBMSは,SQL文を受け取るとまず,そのSQL文を解析します。具体的には,そのSQL文が文法的に正しいかどうかをチェックしたり,選択,射影,結合*1といった処理がそれぞれどのように実施されるかという文の構造を把握します。データベースの管理情報を基に,SQL文に指定したテーブルやフィールドが実際に存在するかどうかや,ユーザーがそれらに対するアクセス権限を持っているかどうかをチェックする処理もここで行います。 (2)SQL文の書き換え解析が終わると,次にRDBMSはSQL文をより高速に実行できるように書き換えます。同じ結果を返すSQL文であっても,具体的な処理内容の違いによって,実行速度は大きく異なります。そこで,処理の手順を工夫したり,演算の種類を変更するといった書き換えをします。書き換えられたSQL文は,最終的にRDBMS内部の処理命令の集まりに変換されます。 (3)実行計画の作成こうして作られたRDBMS内部の処理命令の集まりを実行する方法は,一つとは限りません。例えば,一つのテーブルからデータを取り出す方法(「アクセス・パス」と呼びます)には,テーブル全体を先頭から順に検索していく方法(「全表走査」と呼びます)もあれば,インデックス*2を利用する方法もあります。テーブルを結合する場合など,複数のテーブルを扱う際には,それらを結合するアルゴリズムや結合の順序などにもさまざまな方法が考えられます。検索条件が複雑で,かつテーブルに複数のインデックスが定義されているなら,それらのどれを使うのかも問題になるでしょう。 RDBMSは,処理命令を実行する手続きを何通りか作成したうえで,その中から最も効率の良いものを選択します。こうして出来上がった,RDBMS内部の形式で表された一連の手続きのことを「実行計画」と呼びます。 ただ,複雑なSQL文の場合には,個々のテーブルのアクセス・パスなどの組み合わせは何千通りにもなることがあります。これらをすべて調べていたのではそのために時間がかかってしまい,本末転倒になってしまいます。そこで通常は,最速になりそうな実行計画の候補をある程度絞り込んだうえで比較検討します。 実行計画の作成は比較的時間がかかる処理ですから,SQL文が発行されるたびに行うのでは効率がよくありません。そこで,OracleやMicrosoft SQL Server(以下,SQL Server)などのRDBMSでは,作成した実行計画をキャッシュに保存しておき,同じSQL文が発行されたときにはそのキャッシュ上の実行計画を利用するようになっています。 ここまで来てようやく,SQL文を実行する用意ができたわけです。いかがですか。処理の多さに驚かれている人もいるかもしれませんね。 こうして作成された実行計画は,内部処理命令ごとに実行され,ハードディスクからテーブルのデータなどがキャッシュ・バッファに読み込まれて操作されることになります。実際にハードディスクから読み込む処理の手順などについては,Part2で解説します。 (1)〜(3)の,SQL文を解析して内部形式で表した実行計画を作成するまでの処理を,SQL文の「コンパイル」と呼ぶことがあります*3。Visual BasicやC言語で作成したテキスト形式のソース・ファイルをコンパイルして,CPUが直接解釈できる機械語を生成するのと同じイメージですね。(2)と(3)のSQL文を高速に実行するための処理のことを,「最適化(optimization)」と呼びます。(1)のSQL文の解析は,RDBMSの「パーサー」と呼ばれる機能が,(2)(3)の最適化の処理は「オプティマイザ」という機能が担当します。 推論を行ってSQL文を書き換えるでは,最適化の部分で具体的にどんな処理がなされているのかをもう少し詳しく見ていきましょう。まずはSQL文の書き換えからです。 例えば,table1とtable2という二つのテーブルから,table1のidフィールドの値が10であり,かつtable1とtable2のidフィールドの値が一致するレコードを検索する SELECT * FROM table1, table2
|
布目 綾子 |