⌘+k ctrl+k
1.4 (LTS)
搜索快捷键 cmd + k | ctrl + k
索引

DuckDB 有两种类型的索引:区域映射(zonemaps)和 ART 索引。

区域映射 (Zonemaps)

DuckDB 会自动为所有通用数据类型的列创建区域映射(也称为最小-最大索引)。下推到扫描算子的谓词操作和聚合计算都会使用区域映射。如果使用了过滤条件(例如 WHERE column1 = 123),DuckDB 可以跳过任何最小-最大范围不包含该过滤值的行组(例如,在比较 = 123< 400 时,它可以忽略最小-最大范围为 1000 到 2000 的块)。

排序对区域映射的影响

列内的数据排序程度越高,区域映射索引的价值就越大。例如,最坏的情况下,每一行的列可能包含一个随机数,那么 DuckDB 很可能无法跳过任何行组。如果您使用选择性过滤器查询特定列,最好在插入数据时按这些列预先对数据进行排序。即使是不完美的排序也会有所帮助。有序数据的最佳情况通常出现在 DATETIME 列中。

微基准测试:排序的影响

作为一个例子,让我们重复时间戳的微基准测试,比较使用升序排列的时间戳列与无序时间戳列的效果。

列类型 有序 存储大小 查询时间
DATETIME 1.3 GB 0.6 秒
DATETIME 3.3 GB 0.9 秒

结果表明,仅保持列顺序即可实现更好的压缩,使存储大小缩小了 2.5 倍。它还使计算速度提高了 1.5 倍。

有序整数

利用排序的另一种实用方法是,对于使用选择性过滤器查询的列,使用带有自动增量的 INTEGER 类型,而不是 UUID。在包含乱序 UUID 的表中,DuckDB 必须扫描许多行组才能找到特定的 UUID 值。而有序的 INTEGER 列允许跳过除包含该值以外的所有行组。

ART 索引

DuckDB 允许通过两种方式定义自适应基数树 (ART) 索引。首先,对于具有 PRIMARY KEYFOREIGN KEYUNIQUE 约束的列,会自动隐式创建此类索引。其次,显式运行 CREATE INDEX 语句可在目标列上创建 ART 索引。

在列上使用 ART 索引的权衡如下:

  1. ART 索引能够在变更(插入、更新和删除)期间进行约束检查。
  2. 索引表上的变更性能通常比未索引表差,这是因为这些操作需要维护索引。
  3. 对于某些用例,单列 ART 索引可以提高使用该索引列进行高选择性查询的性能。

ART 索引不会影响连接(join)、聚合和排序查询的性能。

ART 索引扫描

ART 索引扫描会探测单列 ART 索引以获取请求的数据,而不是顺序扫描整个表。探测可以提高某些查询的性能。DuckDB 会尝试对相等性条件和 IN(...) 条件使用索引扫描。它还会将动态过滤器(例如来自哈希连接的过滤器)推送到扫描中,从而允许对这些过滤器进行动态索引扫描。

仅当索引不包含表达式且仅针对单列时,才具备索引扫描资格。例如,以下索引有资格进行索引扫描:

CREATE INDEX idx ON tbl (col1);

例如,以下两个索引具备索引扫描资格:

CREATE INDEX idx_multi_column ON tbl (col1, col2);
CREATE INDEX idx_expr ON tbl (col1 + 1);

索引扫描的默认阈值为 MAX(2048, 0.001 * 表基数)。您可以通过 index_scan_percentageindex_scan_max_count 配置此阈值,或者通过将这些值设置为零来禁用它们。如有疑问,请使用 EXPLAIN ANALYZE 验证您的查询计划是否使用了索引扫描。

索引与内存

DuckDB 通过其缓冲区管理器注册索引内存。然而,这些索引缓冲区目前尚未实现真正的缓冲区管理。这意味着如果需要回收内存,DuckDB 尚无法销毁任何索引缓冲区。因此,索引可能会占用 DuckDB 可用内存的很大一部分,从而可能影响内存密集型查询的性能。重新附加(DETACH + ATTACH)包含索引的数据库可以减轻这种影响,因为我们是延迟反序列化索引内存的。在变更后禁用索引扫描并重新附加,可以进一步降低索引对 DuckDB 可用内存的影响。

索引与打开数据库

索引被序列化到磁盘并在延迟加载,即在重新打开数据库时加载。使用索引的操作只会加载索引中所需的部分。因此,拥有索引不会在打开现有数据库时导致任何减速。

最佳实践:我们建议遵循以下指南

  • 仅在需要强制执行数据约束时才使用主键、外键或唯一约束。
  • 除非您有高选择性的查询并且有足够的可用内存,否则不要定义显式索引。
  • 如果您要定义 ART 索引,请在将数据批量加载到表之后进行。在加载之前添加索引(无论是显式添加还是通过主键/外键添加)都会损害加载性能
© 2025 DuckDB 基金会,阿姆斯特丹,荷兰
行为准则 商标使用指南