索引类型
DuckDB 有两种内置的索引类型。索引也可以通过扩展来定义。
最小-最大索引(区域映射)
一个最小-最大索引(也称为zonemap和块范围索引)会自动为所有通用数据类型的列创建。
自适应基数树 (ART)
一个自适应基数树(ART)主要用于确保主键约束并加速点和非常高度选择性(即小于0.1%)的查询。对于具有UNIQUE
或PRIMARY KEY
约束的列,会自动创建ART索引,并且可以使用CREATE INDEX
来定义。
警告:目前ART索引必须能够放入内存中。如果索引无法放入内存,请避免创建ART索引。
由扩展定义的索引
从版本1.1.0开始,DuckDB通过spatial
扩展支持用于空间索引的R树。
Persistence
最小-最大索引和ART索引都持久化在磁盘上。
CREATE INDEX
和 DROP INDEX
要创建索引,请使用CREATE INDEX
语句。
要删除索引,请使用DROP INDEX
语句。
ART索引的限制
ART索引在第二个位置创建数据的二级副本——这使处理变得复杂,特别是在与事务结合时。在修改也存储在二级索引中的数据时,某些限制适用。
正如预期的那样,索引对性能有显著影响,会减慢加载和更新的速度,但会加快某些查询的速度。详情请参阅性能指南。
更新变为删除和插入
当在索引中的列上执行更新语句时,该语句会被转换为对原始行的删除操作,然后进行插入操作。 这对性能有一定的影响,特别是对于宽表,因为整个行都会被重写,而不仅仅是受影响的列。
过度积极的唯一约束检查
由于事务的存在,数据只能在以下情况下从索引中移除:(1) 执行删除操作的事务已提交,且 (2) 不存在任何引用索引中仍存在的旧条目的事务。因此,执行删除后插入的事务可能会触发意外的唯一约束冲突,因为被删除的元组实际上尚未从索引中移除。例如:
CREATE TABLE students (id INTEGER, name VARCHAR);
INSERT INTO students VALUES (1, 'John Doe');
CREATE UNIQUE INDEX students_id ON students (id);
BEGIN; -- start transaction
DELETE FROM students WHERE id = 1;
INSERT INTO students VALUES (1, 'Jane Doe');
最后一条语句失败,并出现以下错误:
Constraint Error: Duplicate key "id: 1" violates unique constraint. If this is an unexpected constraint violation please double check with the known index limitations section in our documentation (https://duckdb.org/docs/sql/indexes).
这一点,加上更新在同一事务中被转换为删除和插入的事实,意味着在存在唯一或主键约束的情况下更新行通常会导致意外的唯一约束冲突。例如,在以下查询中,SET id = 1
会导致 Constraint Error
发生。
CREATE TABLE students (id INTEGER PRIMARY KEY, name VARCHAR);
INSERT INTO students VALUES (1, 'John Doe');
UPDATE students SET id = 1 WHERE id = 1;
Constraint Error: Duplicate key "id: 1" violates primary key constraint.
If this is an unexpected constraint violation please double check with the known index limitations section in our documentation (https://duckdb.org/docs/sql/indexes).
目前,这是DuckDB的一个预期限制——尽管我们旨在未来解决这个问题。