【问题标题】:Does postgresql have O(1) lookups against the clustered index?postgresql 是否对聚集索引进行 O(1) 查找?
【发布时间】:2016-02-06 21:04:32
【问题描述】:

问题如下:

  1. postgresql(或其他数据库实现)是否对聚集索引进行 O(1) 查找? 即,从行的id(其中id列是聚集索引)直接查找文件系统上的行位置

  2. 如果没有办法进行这样的查找,是否通过 id log2n 查找行?

  3. 考虑到这一点,postgresql 或任何 sql 引擎是否有办法让索引产生其他表中的行的位置以避免这种情况?
  4. postgresql 或任何 sql 引擎是否可以直接查找行(以及与行移动方式相关的生命周期)? 我假设行不会相对于数据库引擎存储格式移动,除非更改聚集索引...

这些问题源于以下实现多对多关系所必需的联结表:

junction_table:

parent_id
child_id

检索一组 child_ids

select * from junction_table where parent_id=parent_value

一个基本正确的实现应该为子行产生一组位置 更糟糕的是,至少有一种方法可以从 child_ids 集中计算子行位置

VS 产生子行方向位置的一对多查询:

one_to_many_child_table:

id
name
parent_id

select * from child_table where p_id=parent_value

【问题讨论】:

  • 数据库系统中大部分索引都是B+树实现的,所以算法复杂度是O(log n)。哈希算法是 O(1),但很少实现

标签: mysql sql postgresql indexing


【解决方案1】:

许多问题 -- 让我提到每一个,把各个部分放在一起。

BTrees,本质上是 O(logn)。但是,您几乎可以将其视为 O(1)。 BTree 通常在每个节点中可能有 100 个子链接。也就是说,一百万行只有 3 层深; trillion 行大约有 6 层深。

此外,LRU 缓存(如 MySQL 在块级别所做的)倾向于将至少非叶节点保留在缓存中。 (在缓存中拥有你需要的东西是大型数据库的真正优化。)

B+Tree -- 取一个 BTree 并在叶子节点之间添加双向链接。这使得“范围扫描”非常有效。

B+Tree 索引是“最好的整体”。

聚类 在这种情况下,假设“聚类”意味着唯一的行标识符与数据一起存储。 (对于 MySQL,这是 PRIMARY KEY;其他一些我们是 'rownum'。)

PRIMARY KEY 可能是集群的和/或唯一的——这因数据库实现而异。

辅助键通常是一个 BTree,但从它获取数据的实现方式不同。它可能直接指向数据;它可能有一个“rownum”,可用于查找记录;或者它可能具有主键的副本,从而允许通过 PK 查找行。

MyISAM 的 InnoDB -- PRIMARY KEY 与数据聚集在一起,组织为 B+Tree,并且是唯一的。这意味着PK的点查询将在BTree中进行一次潜水以找到整行。

InnoDB 中的Secondary key 有一个单独的BTree,并且在叶子节点中找到了PK 的副本。因此,次键查找是两次潜水(一次在次 BTree 中,一次在 PK+data BTree 中)。也就是说,除非索引是“覆盖”并且所有需要的列(对于 SELECT)都在辅助键 + 主键中找到。

MySQL 的 MyISAM -- MySQL 的旧引擎(已经失宠)将 PRIMARY KEY 和辅助键都实现为 BTree,其中叶节点在数据文件中具有字节地址。因此,这两种类型的密钥都涉及一个 BTree 潜水加上一个文件系统“搜索”到另一个文件。

哈希 -- 真正的 O(1) 查找需要完美的哈希。没有人实现这一点。然而 some 实现有一个 Hash + 某种形式的处理溢出。所以有时是 O(1),有时会慢一点。 (MySQL 在其 MEMORY 引擎上提供了 Hash。)

Rownum / Rowid -- 这是让 db 直接进入行的某种数字。例如,Oracle 就使用这种东西。但是,您必须首先将您的密钥映射到 rownum。所以,这有点像一个两步的过程。 (MySQL 不使用 Rownum/Rowid。)

一对多 -- 在任何情况下,使 1:many 有效的索引将在索引中将“many”聚集在一起,但可能有“rows” " 他们指向散落在各处的数据。

Postgresql(我不知道 Postgres 是如何工作的。)

【讨论】:

    猜你喜欢
    • 2014-08-27
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多