by Hayato Matsuura.

応答時間スループット、そして水平スケール


高価なハードウェアを使うようにしたからと言って、必ず処理が高速になるとは 限りません。しかし、通常はそれでたくさんの処理を行うことが可能になります。 高価なハードウェアは、高速な車と言うより、広い高速道路に例えるべきでしょう。 つまり、それ自体によってスピードを出すことはできないし、それが許されていないかもしれません。しかし、多くの車線はあるのです。これが、ハード ウェアに投資しても、必ずしも遅いSQLクエリを速くすることにつながらない理由です。

今や90年代ではありません。その頃、CPUコア1つの計算性能は急速に向上していました。多くの応答時間の問題は、新しいハードウェアを 導入することで解消されました。CPUが高速になったからです。それはさながら毎年旧モデルの2倍高速な新しいモデルの車が発売されるような ものでした。しかし、21世紀初めの数年間で、1CPUコアあたりの処理能力は頭打ちになり、その点での改善はほとんど見られなくなりました。 より高性能なCPUを発売し続けるため、各ベンダはマルチコア戦略を取り始めました。しかしそれは、複数のタスクを同時に処理することはできても、 1つしかタスクがない時のパフォーマンスを上げることはできません。つまり、 パフォーマンスを複数の側面から考える必要があるようになったのです。

水平方向のスケール(サーバの追加)にも、同じ制限があります。より多くのサーバがあればよりたくさんのリクエストを処理できますが、 個々のクエリの応答時間は高速にはなりません。検索を高速にするには、CouchDBMongoDBと いったリレーショナルでないシステムの場合も含め、効率的な検索ツリーが必要になります。

重要

リレーショナルなSQLデータベースかリレーショナルでないシステムかに 関わらず、正しいインデックスを作ることは、クエリの応答時間を短くする最善の方法です。

適切なインデックスを作るのはすなわち、Bツリーインデックス対数スケーラビリティの威力を十分に引き出すことです。しかし残念なことに、インデックスの作成は 非常にずさんに行われることも多いのです。データ量に対する応答時間の図では、そういったずさんなインデックスを明らかにするものです。

図データ量に対する応答時間

ずさんなインデックスと正しいインデックスの応答時間の違いは 驚くほどはっきりしています。この違いを、ハードウェアを追加することで埋め合わせるのは難しいでしょう。例えハードウェアによって応答時間を 小さくしようとしても、それが最善の方法なのかについては疑問が残ります。

いわゆるNoSQLシステムの多くは、あらゆるパフォーマンス問題はスケールアウトで解決できるとしています。ただし、ここで言う スケーラビリティは、多くの場合書き込み処理を対象にしていて、結果整合性(eventual consistency) モデルに従ったものです。SQLデータベースは書き込み処理を遅くする原因になる厳密な整合性モデルを採っていますが、それが必ずしも スループットが悪いことを示すわけではありません。これについての詳細は、結果整合性とCAP定理という題のボックスを参照してください。

結果整合性とCAP定理

分散システムにおいて厳密な整合性を保とうとすると、ノード間での あらゆる書き込み処理を同期的に行う必要があります。この原理には、次の2つの好ましくない副作用があります。(1) レイテンシと応答時間が 増加します。(2) 書き込みを完了させるために、同時に複数のメンバが有効な状態でなければならないので、全体の可用性が低下します。

分散SQLデータベースは、共有ストレージを 使ったり、マスタスレーブレプリケーションを使用した計算機クラスタと 混同されることがあります。実際、分散データベースはERPで 統合されたウェブショップによく似ています。そこでは、2つの商品がある時は、それぞれが別のベンダから購入したものです。2つのベンダの システム間に整合性があるということは、2相 コミット(2PC)プロトコルを使った理想的なゴールです。このプロトコルは、複数のデータベースに渡っていわゆる 「全部あり、あるいは全部なし(all-or-nothing)」な振る舞いをする グローバルトランザクションを実行します。グローバルトランザクションが成功するには、関係する全てのメンバが有効な状態でなければなりません。 このため、全体の可用性が下がってしまうのです。

分散システムのノードが増えると、厳密な整合性を担保するのが難しくなります。ノード数が数台を超えただけで、厳密な整合性を保つのは ほとんど無理になってしまいます。その一方で、整合性を犠牲にすることで、可用性の問題を解決し、応答時間の増大を阻止できます。 このアイディアの基本は、ノードの一部に対する書き込み処理が終わった後で、グローバルな整合性を回復するというものです。しかしこの方法には、ある 1つの問題が残されます。矛盾した変更が2台以上のノードで行われてしまう ことを防げないのです。矛盾を防ぐのではなく、 うまく扱うことで、結果的に 整合性が取れるのです。つまりこの考え方だと、整合性が取れているというのは、全てのノードのデータが正しい、あるいは最適な データであることではなく、同じデータを持ってさえいればいいということになります。

BrewerのCAP 定理は、 一貫性(Consistency)、 可用性(Availability)、 分断耐性(Partition tolerance)の3つの間にある 依存についての一般性を述べたものです。

ハードウェアを増やしても、通常は応答時間は改善されません。実際には、システムが複雑になることでレイテンシが蓄積するため、システムは 遅くなってしまう可能性すらあり得ます。アプリケーションとデータベースが同じコンピュータ上で動作している場合、ネットワークのレイテンシは 問題になりませんが、本番環境ではデータベースとアプリケーションをそれぞれ専用のハードウェアで動かすことが多いので、そういった構成は 一般的ではありません。セキュリティポリシー上、アプリケーションサーバとデータベースの間にファイアウォールを置かなくてはならない時もありますが、 これもネットワークレイテンシを倍増させる原因になります。インフラが複雑になればなるほど、レイテンシが積み重なり、応答時間は遅く なっていきます。こう言ったことが、高価な本番用ハードウェアが、安価なデスクトップPCの開発環境よりも遅いという、直感に反する振る舞いにつながる ことがあります。

協力してください

この記事が気に入ったら、私の書いた本「SQLパフォーマンス詳解」や私によるトレーニングもきっと気にいるはず。

もう1つ非常に重要なレイテンシに、ディスクのシークタイムがあります。 回転するハードディスク(HDD)は、要求したデータを読み込むために機械的なパーツを指定した場所に動かすのに、通常数ミリ秒という比較的長い時間を 要します。この時間は、4階層のBツリーを走査する時には4倍かかるわけですから、 合わせて数十ミリ秒かかることになります。それはコンピュータにとっては永遠に思われる程の時間ですが、1度しか行われない処理なら、我々の認識できる 長さとまではいかないでしょう。しかし、1つのSQL文で数百、場合によっては数千回のディスクシークが起きることも普通にあることで、特に複数の テーブルを結合する時にはなおさらです。キャッシュによってこういった問題は劇的に改善されますし、SSDのような新技術によって、 シークタイムは桁違いに減りますが、それでもなお結合は遅い処理だと言えるのではないでしょうか。次の章では、効率のよいテーブル結合のための インデックスの使い方を説明します。

SSD (Solid State Disk)キャッシュ

SSD (Solid State Disks)は、稼働部品のない大容量記憶装置です。 SSDの通常のシークタイムは、HDDのシークタイムと比べると桁違いに 高速です。SSDは、2010年ごろにはエンタープライズ向けのストレージとして使われるようになりましたが、コストが高いことと寿命が短いため、 データベースではあまり一般的に使われていませんでした。

データベースは、アクセス頻度の高いデータを主記憶にキャッシュします。これは、インデックスリーフノードのようにインデックスへの アクセスの度に必要なデータには特に便利な仕組みです。データベースは、インデックスの走査の度にディスクシークが起きないように、よく使われる インデックスを完全にキャッシュします。

事実

  • パフォーマンスには、2つの側面があります。応答時間と、スループットです。

  • ハードウェアを増やしても、クエリの応答時間は通常は改善されません。

  • クエリの応答時間を改善する唯一の方法は、適切なインデックスを作ることです。

著者について

Markus Winandの写真

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

彼の本

カバー『SQLパフォーマンス詳解』

核心をわかりやすく 解説。

Markusから購入します
(送料無料+PDF)

Amazonで購入
(印刷版のみ)

“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