主键索引是一种优化,用于查找磁盘上保存该行的位置。作为一个结构,它只包含 PK 数据,而不是整行。
在数据库上,性能通常取决于从磁盘读取的页面数量与缓存的数量。由于 PK 索引小于整个表,它更有可能在缓存中,它导致从磁盘读取的块更少,从缓存中删除的其他表的块也更少。因此,这是一项重大的性能优化。
此外,在修改表数据时,行被锁定。如果从磁盘上的表数据中扫描主键,锁定的行会减慢所有其他查询的访问速度。通过将索引分离为一个单独的结构,即使指向的行被锁定,也可以使用索引。
所以总的来说,单独的 PK 结构是一种经典的时空优化。
EDIT 表格中各行的顺序是什么?以下答案适用于 Oracle,但适用于许多数据库。
简短回答:行在磁盘上没有排序,这就是 PK 索引(和其他索引)如此重要的原因。
长答案:
虽然主键 b 树结构必须排序(b 树),但表的行分散在表空间中。为了理解这一点,我们需要深入了解各种数据结构。
首先,数据库被结构化为称为表空间的逻辑实体。表空间是一个或多个磁盘上的一个或多个文件中的空间。文件开始为空。当表空间变满时(从技术上讲,当其中的数据达到阈值时)表空间可以自动增长。它也可以通过放大文件(添加“范围”或添加新文件)手动增长。表空间可以集群在多台机器和磁盘上。
第二:一个表空间被划分为段,每个段供单个表或索引使用。
第三:段被分成块,每个块有一个或多个行的空间。这些块不与磁盘或操作系统块相同; Oracle 块是一个或多个 OS 块。 (这是为了可传输性,以及管理具有不同块大小的媒体)。
在插入时,数据库将从表空间中的任何位置选择块中的空间。该行可以按顺序插入(尤其是批量插入到空表中),但通常数据库也会重用由于某些类型的更新而删除或移动行的空间。虽然该位置在理论上是可预测的,但实际上您不应依赖或期望将行放置在任何特定块中。
Oracle 中一个有趣的事情是 ROWID。这是存储在索引中的引用,允许数据库查找行:
- 扩展的 rowid 具有四部分格式 OOOOOOFFFBBBBBBRRR:
- 前 6 个字符 OOOOOO 表示数据对象编号,使用 32 位
- 接下来的 3 个字符 FFF 表示与表空间相关的数据文件编号,使用 10 位。
- 接下来的 6 个字符 BBBBB 表示块号,使用 22 位。
- 最后3个字符RRR代表行号,使用16bit
更多详情,请参阅http://docs.oracle.com/cd/E11882_01/server.112/e25789/logical.htm#autoId0
另一个想法:在 DB 世界中有一个名为 partitions 的概念,其中根据某些表达式逻辑将数据集划分为不同的表空间(通常是集群中不同的磁盘或节点)。例如,在客户表上,垂直分区可以由个人所在的国家/地区定义。这样您就可以确保美国客户在物理上位于一个磁盘上,而澳大利亚客户在另一个磁盘上。