80

私はここ数年データベースを扱ってきましたが、データベースをかなり使いこなせるようになったと思います。しかし、最近Joelのリーク抽象化の法則について読んでいて、データベースから必要なものをほぼすべて取得するためのクエリを記述できるにもかかわらず、データベースが実際にクエリをどのように解釈するのかわからないことに気付きました。データベースが内部でどのように機能するかを説明する良い記事や本を知っている人はいますか?

私が興味を持っているいくつかの特定のものは次のとおりです。

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

5 に答える 5

85

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

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

ここで、「table.name」フィールドがインデックス化されている場合、データベースは最初にインデックスを使用して (可能性は高いですが、必ずしもそうとは限りません)、実際のフィルターを適用する候補レコードを見つけます。

これにより、式を適用する候補レコードの数が減ります。それ以外の場合は、「テーブル スキャン」と呼ばれるもの、つまりすべての行を読み取るだけです。

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

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

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

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

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

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

B+Trees は通常、調べる必要があります。これは、何年も前からある簡単なテクニックです。その利点は、ほとんどのバランス ツリーと共有されます。ノードへの一貫したアクセスに加えて、すべてのリーフ ノードがリンクされているため、ノードからノードへキーの順序で簡単にトラバースできます。したがって、インデックスを使用すると、行はデータベース内の特定のフィールドに対して「並べ替えられた」と見なすことができ、データベースはその情報を活用して最適化に役立てることができます。これは、たとえば、インデックスにハッシュ テーブルを使用する場合とは異なります。ハッシュ テーブルでは、特定のレコードにすばやくアクセスすることしかできません。B ツリーでは、特定のレコードだけでなく、並べ替えられたリスト内のポイントにすばやく到達できます。

データベースに行を格納してインデックスを作成する実際のメカニズムは、非常に単純明快であり、よく理解されています。ゲームはバッファを管理し、SQL を効率的なクエリ パスに変換して、これらの基本的なストレージ イディオムを活用します。

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

于 2008-10-06T01:40:23.973 に答える
4
  • selectステートメントに一致するものを見つけるためにデータベースは実際に何をしますか?

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

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

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

    データにすばやくアクセスするためのメモリマップファイル

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

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

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

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

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

于 2008-10-06T00:53:26.860 に答える
1

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

于 2008-10-06T02:17:23.977 に答える
0

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

説明を書いてみましたが、これはあまりにも大きな話題です。Hellersteinの記事(Saifがリンクしているバークレーサーバー上の記事)をチェックしてから、詳細について質問してください。

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

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

于 2008-10-06T01:23:25.460 に答える
0

詳細を知りたい場合は、sqlite のソースを入手して、それがどのように機能するかを確認することをお勧めします。大規模なオープン ソース データベースや商用データベースほどの規模ではありませんが、完成しています。詳細を知りたい場合は、SQLiteの優れた説明であるだけでなく、私が知っている最も読みやすい技術書の 1 つであるSQLite の決定版ガイドをお勧めします。MySQL 側では、 MySQL パフォーマンス ブログから学ぶことができます。また、ブログが著者の 1 人であるO'Reilly High Performance MySQL (V2) の本の表紙でも学ぶことができます。

于 2008-10-06T02:26:59.870 に答える