by Hayato Matsuura.

開発者はインデックスを知る必要がある


SQLのパフォーマンス問題は、SQLそのものと同じぐらいの歴史がある―― ある人は、SQLはそもそも遅いものだとすら言うかもしれません。これは、 SQLの歴史が始まった頃は正しかったかもしれませんが、今となっては全く 当てはまらないでしょう。にもかかわらず、SQLのパフォーマンス問題は今も 一般的でよくあることです。どうしてそうなってしまうのでしょうか?

SQL言語は、恐らく最も成功した第4世代言語(4GL)でしょう。その最大の 利点は、「何を」「どのように」 を分離できることです。SQL文は、どのようにそれを 実行するかを記述せずに、単純に 何を必要としているか のみの記述になっています。以下のような例を考えてみましょう。

SELECT date_of_birth
  FROM employees
 WHERE last_name = 'WINAND'

SQLのクエリは、データを要求する英語の文として読むことができます。 通常SQLを書く時には、データベースの内部動作やストレージシステム(ディスクや ファイルなど)に関する知識は必要とされません。データベースに対して、どの ファイルを開き、どのように要求する行を見つけるかを指示する必要はないわけです。 多くの開発者は、何年もSQLを触っているにもかかわらず、データベースの内部で 行われている処理についてはほとんど知らないでしょう。

何が欲しいのかと、どのようにそれを取得するかという関連性を分離することは、 SQLにおいては非常に有効に機能しています。しかし、それでも完璧ではありません。 パフォーマンスの問題にたどり着く時、このような抽象化は逆効果になります。 前述の通り、SQL文を書く人は、どのようにデータベースが 文を実行するかを知らないからです。つまり、SQL文を書いた人はクエリの実行が 遅くても責任を持てないのです。しかし、経験的には逆のことが言えるでしょう。 つまり、パフォーマンス上の問題を避けるためには、開発者はデータベースについて 多少なりとも知っておく必要があるということです。

すなわち、開発者が知るべき唯一のことは、 どのようにインデックスを張るか、ということになります。データベースに インデックスを張ることは、実際のところ、開発のタスクのひとつです。それは、 正しいインデックスを張るのに最も重要な情報は、ストレージシステムの設定や ハードウェアの構成ではないからです。データへのアクセスパスに関する情報は、 データベース管理者(DBA)や外部のコンサルタントには詳しく分からないことです。 アプリケーションをリバースエンジニアリングしてそういった情報を集めるのは、 かなりの時間を要することでしょう。一方で、開発者はこの情報を知っているに 違いないのです。

この本では、インデックスについて開発者が知るべきこと全てを 書いていますが、それ以上のことは扱いません。さらに詳しく言うと、この本では 最も重要なインデックスである、Bツリーインデックスのみを 取り上げます。

Bツリーインデックスは、多くのデータベースでほぼ同じように動作します。 この本ではOracleデータベースの用語のみを使いますが、他のデータベースの対応する用語にも 言及するようにしています。補足として、MySQL、PostgreSQL、 SQL Serverに関する詳しい情報も掲載します。

この本の構成は、開発者向けに考えられたものになっています。ほとんどの 章は、SQL文の構成要素に対応するように書かれています。

第1章 - インデックスの内部構造

最初の章は唯一、特定のSQL文を扱いません。インデックスの基本的な 構造についての章です。インデックス構造を理解するのは、この後の章を理解 するための基礎になるので、読み飛ばさないように!

この章は8ページと比較的短いですが、一通り読み進めれば、 インデックスを使っているのに実行が遅い原因が理解できるように なるでしょう。

第2章 - WHERE句

ここは全力を尽くして取り組むべきところです。この章では、 とてもシンプルな1カラムだけの検索から、範囲検索、 そしてLIKEのような特別なものまで、 where句の全ての特徴について説明します。

この章は、この本の最も重要な部分を構成しています。 ここで書かれていることを学べば、より高速に動作するSQL文を 書けるようになるでしょう。

第3章 - パフォーマンスとスケーラビリティ

少し脱線して、パフォーマンスの計測と、データベースの スケーラビリティについての章です。ハードウェアを増強することが クエリが遅いことに対する最適解ではないのはなぜか、理解しましょう。

第4章 - 結合処理

SQLの話に戻ります。高速なテーブルの結合のためにどのように インデックスを使うべきかの説明です。

第5章 - データのクラスタリング

ある1カラムだけをselectするのと、全カラムをselectすることに違いが あるかどうか疑問に思ったことはないでしょうか? その答えと、より高い パフォーマンスを引きだすための方法について書きます。

第6章 - ソートとグルーピング

order bygroup byでも インデックスを使う方法について扱います。

第7章 - 部分的結果

この章では、実行結果全体が欲しいわけではない時に、 「パイプライン化」した実行の恩恵を受ける方法を説明します。

第8章 - 挿入、削除、更新

インデックスは書き込みのパフォーマンスにどのように影響を 与えるのでしょうか? インデックスを張るのはタダではありません。賢く 使いましょう!

付録A - 実行計画

SQL文がどのように実行されるのか、データベースに問い合わせて みましょう。

付録B - SQLに関する都市伝説

いくつかのよく聞かれるSQLに関する都市伝説と、それに関する 説明を挙げます。この本が改善されるに従って増えていくことでしょう。

付録C - スキーマ例

この本に登場するテーブル全てのcreate文と insert文です。

著者について

Markus Winandの写真

Markus Winand氏は、開発者がSQLパフォーマンスを改善するお手伝いをしています。彼は、SQL Performance Explainedの 著者でもあり、出張トレーニングhttp://winand.at/での リモート講義も 行っています。

“Use The Index, Luke!” by Markus Winand is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.
法律上の通知 | 接触 | 無保証 | 商標 | Privacy | CC-BY-NC-ND 3.0 license