⌘+k ctrl+k
1.1.3 (stable)
Search Shortcut cmd + k | ctrl + k
Indexing

DuckDB有两种类型的索引:zonemaps和ART索引。

Zonemaps

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

排序对Zonemaps的影响

列中的数据越有序,zonemap索引就越有用。例如,在最坏的情况下,列中的每一行可能包含一个随机数。DuckDB将不太可能跳过任何行组。有序数据的最佳情况通常出现在DATETIME列中。如果特定列将通过选择性过滤器进行查询,最好在插入数据时按这些列预先排序数据。即使是不完美的排序仍然会有所帮助。

微基准测试:排序的影响

举个例子,让我们重复使用一个按升序排序的时间戳列与一个未排序的时间戳列进行时间戳的微基准测试

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

结果表明,简单地保持列顺序可以改善压缩效果,使存储大小减小2.5倍。 同时,它还可以使计算速度提高1.5倍。

有序整数

另一种利用排序的实用方法是,对于将使用选择性过滤器查询的列,使用INTEGER类型并自动递增,而不是使用UUIDUUID可能会以随机顺序插入,因此需要扫描表中的许多行组才能找到特定的UUID值,而有序的INTEGER列将允许跳过所有行组,除了包含该值的行组。

ART 索引

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

在列上拥有ART索引的权衡如下:

  1. 它能够在非大量更改(插入、更新和删除)时进行高效的约束检查。
  2. 与非索引性能相比,拥有ART索引会使受影响列的更改变慢。这是因为这些操作需要进行索引维护。

关于查询性能,ART索引有以下影响:

  1. 它使用索引列加速点查询和其他高度选择性的查询,其中过滤条件返回大约0.1%或更少的所有行。如有疑问,请使用EXPLAIN来验证您的查询计划是否使用了索引扫描。
  2. ART索引对连接、聚合和排序查询的性能没有影响。

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

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

  • 仅当这些是强制执行数据约束所必需时,才使用主键、外键或唯一约束。
  • 除非您有高度选择性的查询,否则不要定义显式索引。
  • 如果您定义了ART索引,请在将数据批量加载到表之后进行。在加载之前添加索引,无论是显式地还是通过主键/外键,都会对加载性能产生不利影响