web-dev-qa-db-ja.com

データベースは内部的にどのように機能しますか?

私は過去数年間データベースを扱ってきましたが、データベースの使用にかなりの能力を身につけたと思いたいと思います。しかし、私は最近ジョエルの Law of Leaky Abstractions について読んでいたので、データベースから必要なものをほとんど取得するためのクエリを作成できても、データベースが実際にどのように解釈されるかわかりませんクエリ。データベースが内部でどのように機能するかを説明する良い記事や本を知っている人はいますか?

私が興味を持っている特定の事柄は次のとおりです。

  • Selectステートメントに一致するものを見つけるために、データベースは実際に何をしますか?
  • データベースは、複数の「where key1 = key2」ステートメントを含むクエリへの結合を異なる方法でどのように解釈しますか?
  • データベースはすべてのメモリをどのように保存しますか?
  • インデックスはどのように保存されますか?
76
Bonnici

Selectステートメントに一致するものを見つけるために、データベースは実際に何をしますか?

率直に言って、それは総当たりの問題です。単純に、データベース内の各候補レコードを読み取り、式をフィールドに一致させます。そのため、「select * from table where name = 'fred'」がある場合、各レコードを文字通り実行し、「name」フィールドを取得して、「fred」と比較します。

現在、「table.name」フィールドにインデックスが付けられている場合、データベースは(おそらくではないが)インデックスを最初に使用して、実際のフィルターを適用する候補レコードを見つけます。

これにより、式を適用する候補レコードの数が減ります。そうしないと、「テーブルスキャン」と呼ばれる処理、つまりすべての行の読み取りが実行されます。

しかし、基本的には、候補レコードの位置を特定することは、実際のフィルター式を適用する方法とは別であり、明らかに、実行できる巧妙な最適化がいくつかあります。

データベースは、複数の「where key1 = key2」ステートメントを含むクエリへの結合を異なる方法でどのように解釈しますか?

さて、結合は、フィルターが適用される新しい「疑似テーブル」を作成するために使用されます。したがって、フィルター基準と結合基準があります。結合基準を使用してこの「疑似テーブル」を作成し、それに対してフィルターが適用されます。今、結合を解釈するとき、それは再びフィルターと同じ問題です-「疑似テーブル」のサブセットを構築するためのブルートフォース比較とインデックス読み取り。

データベースはすべてのメモリをどのように保存しますか?

優れたデータベースの鍵の1つは、I/Oバッファの管理方法です。しかし、基本的にRAMブロックをディスクブロックに一致させます。最新の仮想メモリマネージャを使用すると、より単純なデータベースは、メモリバッファマネージャとしてVMハイエンドDB'Sはこれらすべてを自分で行います。

インデックスはどのように保存されますか?

Bツリーは通常、検索する必要があります。これは、長年にわたって使用されてきた単純な手法です。ノードへの一貫したアクセスに加えて、すべてのリーフノードがリンクされているため、キーオーダーでノード間を簡単に移動できるため、ほとんどのバランスツリーで利点が共有されます。そのため、インデックスを使用すると、データベース内の特定のフィールドに対して行が「ソート」されたと見なされ、データベースはその情報を活用して最適化に役立てることができます。これは、たとえば、インデックスにハッシュテーブルを使用することとは異なります。ハッシュテーブルを使用すると、特定のレコードにすばやくアクセスできます。 Bツリーでは、特定のレコードだけでなく、ソートされたリスト内のポイントにすばやく到達できます。

データベースに行を格納およびインデックス付けする実際の仕組みは、非常に単純明快でよく理解されています。ゲームはバッファを管理し、これらの基本的なストレージイディオムを活用するためにSQLを効率的なクエリパスに変換しています。

次に、ストレージイディオムに加えて、マルチユーザー全体、ロック、ロギング、トランザクションの複雑さがあります。

80
Will Hartung
  • Selectステートメントに一致するものを見つけるために、データベースは実際に何をしますか?

    DBはインデックスを使用しています(以下を参照)

  • データベースは、複数の「where key1 = key2」ステートメントを含むクエリへの結合を異なる方法でどのように解釈しますか?結合操作は、ツリーをマージすることにより、バイナリツリー操作に変換できます。

  • データベースはすべてのメモリをどのように保存しますか?

    メモリマップされたファイルによりデータへのアクセスが高速化

  • インデックスはどのように保存されますか?

    内部的には、DBはインデックス作成のためにBツリーと連携しています。

これについては、ウィキペディアで詳しく説明する必要があります。

http://en.wikipedia.org/wiki/B-tree

http://en.wikipedia.org/wiki/Database

4
Peter Parker

読むだけでなく、DBツールを使用して、データベースがクエリで使用する実行計画を調べることも有益です。それがどのように機能するかについての洞察を得ることに加えて、より良いフィードバックループでクエリを最適化するテクニックを試すことができます。

1
Turnkey

サイフ、素晴らしいリンク。ほとんどのトピックをカバーし、特定のベンダーの実装に関する詳細を提供するための管理の概要。

説明を3回試みましたが、これは非常に大きなトピックです。 Hellersteinの記事(Saifがリンクしたberkeleyサーバーに関する記事)を確認してから、詳細を尋ねてください。

特定のDBMSには「既知の優れたアイデア」のサブセットのみが実装されていることに注意してください。たとえば、SQLiteはハッシュ結合さえ行わず、ネストされたループのみを実行します(ack !!)。しかし、それから、それは簡単に埋め込み可能なdbmsであり、非常にうまく機能します。そのため、複雑さの欠如について言わなければならないことがあります。

DBMSが統計を収集する方法と、それを使用してクエリプランを構築する方法、そしてそもそもクエリプランを読み取る方法を学習することは、非常に貴重なスキルです。学ぶ、こ​​れを学ぶ。それは世界に違いをもたらします(そして、誤ってデカルト積を再び書くことは決してありません... ;-))。

0
SquareCog

さらに詳しく知りたい場合は、sqliteソースを入手して、それがどのように行われるかを確認することをお勧めします。大規模なオープンソースおよび商用データベースの規模ではありませんが、完全です。もっと詳しく知りたい場合は SQLiteの最終ガイド をお勧めします。これはsqliteの優れた説明であるだけでなく、私が知っている最も読みやすい技術書の1つでもあります。 MySQL側では、 MySQL Performance Blog から学ぶことができます。また、本の前でO'Reilly High Performance MySQL (V2)作家たち。

0
dajobe