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ツリーインデックスのみを取り上げます。
協力してください
この記事が気に入ったら、私の書いた本「SQLパフォーマンス詳解」や私によるトレーニングもきっと気にいるはず。
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 by
とgroup by
でもインデックスを使う方法について扱います。- 第7章 - 部分的結果
この章では、実行結果全体が欲しいわけではない時に、「パイプライン化」した実行の恩恵を受ける方法を説明します。
- 第8章 - 挿入、削除、更新
インデックスは書き込みのパフォーマンスにどのように影響を与えるのでしょうか? インデックスを張るのはタダではありません。賢く 使いましょう!
- 付録A - 実行計画
SQL文がどのように実行されるのか、データベースに問い合わせてみましょう。
- 付録B - SQLに関する都市伝説
いくつかのよく聞かれるSQLに関する都市伝説と、それに関する 説明を挙げます。この本が改善されるに従って増えていくことでしょう。
- 付録C - スキーマ例
この本に登場するテーブル全ての
create
文とinsert
文です。
ヒント
著者の発表スライド「インデックス ――ないがしろにされがちな、しかしパフォーマンス改善のオールラウンダー」