主キー インデックスは、行が保持されているディスク上の場所を見つけるための最適化です。構造体として、行全体ではなく、PK データのみが含まれます。
データベースでは、多くの場合、ディスクとキャッシュから読み取られるページ数によってパフォーマンスが左右されます。PK インデックスはテーブル全体よりも小さいため、キャッシュに存在する可能性が高くなり、ディスクから読み取られるブロックが少なくなり、キャッシュから削除される他のテーブルのブロックが少なくなります。したがって、これは主要なパフォーマンスの最適化です。
さらに、テーブル データの変更中は、行がロックされます。主キーがディスク上のテーブル データからスキャンされている場合、ロックされた行により、他のすべてのクエリへのアクセスが遅くなります。インデクスを別構造にすることで、指している行がロックされている状態でもインデクスを利用することができます。
したがって、全体として、個別の PK 構造は古典的な空間対時間の最適化です。
編集テーブル内の行の順序は? 次の回答は Oracle 用ですが、多くのデータベースに適用できます。
簡単な答え: 行はディスク上で順序付けされていないため、PK インデックス (およびその他のインデックス) が非常に重要です。
長い答え:
主キーの B ツリー構造 (B ツリー) は必然的にソートされますが、テーブルの行はテーブル スペース全体に散らばっています。これを理解するには、さまざまなデータ構造をドリルダウンする必要があります。
まず、データベースはテーブルスペースと呼ばれる論理エンティティに構造化されます。テーブルスペースは、1 つ以上のディスク上の 1 つ以上のファイル内のスペースです。ファイルは空で始まります。表領域がいっぱいになると (技術的にはその中のデータがしきい値に達すると)、表領域は自動的に拡張されます。また、ファイルを拡大する (「エクステント」を追加する、または新しいファイルを追加する) ことにより、手動で拡張することもできます。表領域は、複数のマシンおよびディスクにわたってクラスタ化できます。
2 つ目: テーブルスペースはセグメントに分割され、各セグメントは単一のテーブルまたはインデックスを使用します。
3 番目: セグメントはブロックに分割され、各ブロックには 1 つ以上の行のスペースがあります。これらのブロックは、ディスクまたは OS ブロックと同じではありません。Oracle ブロックは、1 つ以上の OS ブロックです。(これは、可搬性のため、および異なるブロック サイズのメディアを管理するためです)。
挿入時に、データベースはテーブルスペースのどこからでもブロック内のスペースを選択します。行は順次挿入できます (特に空のテーブルへの一括挿入) が、通常、データベースは、ある種の更新のために行が削除または移動された領域も再利用します。配置は理論的にはある程度予測可能ですが、実際には、行が特定のブロックに配置されることに依存したり、期待したりしないでください。
Oracle で興味深いのは ROWID です。これは、DB が行を検索できるようにするインデックスに格納されている参照です。
- 拡張 ROWID は 4 ピース形式 OOOOOOFFFBBBBBBRRR です。
- 最初の 6 文字 OOOOOO は、32 ビットを使用したデータ オブジェクト番号を表します
- 次の 3 文字の FFF は、10 ビットを使用したテーブルスペース相対データファイル番号を表します。
- 次の 6 文字 BBBBB は、22 ビットを使用してブロック番号を表します。
- 最後の 3 文字の RRR は、16 ビットを使用して行番号を表します
詳細については、http://docs.oracle.com/cd/E11882_01/server.112/e25789/logical.htm#autoId0を参照してください。
もう 1 つの考え: DB の世界にはpartitionsと呼ばれる概念があり、データセットはいくつかの式ロジックに応じて異なるテーブルスペース (多くの場合、クラスター内の異なるディスクまたはノード) に分割されます。たとえば、顧客のテーブルでは、その人物の国によって垂直パーティションを定義できます。こうすることで、米国の顧客が 1 つのディスクに物理的に存在し、オーストラリアの顧客が別のディスクに存在することを確認できます。