假设有一张如下结构的数据表:
CREATE TABLE test1 (
id integer,
content varchar
);
应用程序频繁发起如下模式的等值查询:
SELECT content FROM test1 WHERE id = constant;
在没有任何前置辅助结构的情况下,数据库系统必须自始至终逐行顺序扫描整张 test1 表以寻找所有匹配项。如果表中有海量数据行而该查询仅命中极少量记录(通常为 0 行或 1 行),这种逐行全表扫描无疑极度低效。如果预先指示系统在 id 列上维护一棵索引树,系统就能以高得多的效率定位目标行(例如仅需沿着 B 树向下遍历寥寥数层索引块即可精准命中)。
这与图书末尾的关键词索引极为相似:读者经常检索的专有名词和核心概念会被提取并按字母序汇聚在书末的索引表中。读者可以通过快速翻查索引直达对应页码,而不必从头通读整本书来寻找所需内容。正如作者需要预先洞察读者可能会翻阅哪些词条一样,数据库架构师的职责正是准确预见哪些索引能够最大化加速业务查询。
在指定字段上创建索引的基础命令如下:
CREATE INDEX test1_id_index ON test1 (id);
索引名称 test1_id_index 可以自由命名,但推荐选取能够清晰体现其表名和用途的规范标识。
要删除既有索引,使用 DROP INDEX 命令。索引可以随时按需创建或随时安全移除,不影响底层基表数据的完整性。
索引创建完毕后无需人工日常干预:当基表数据发生增删改时,系统会在底层自动同步维护更新索引;在处理查询时,只要优化器判定走索引比顺序全表扫描成本更低,便会自动选择索引扫描路径。为了确保优化器能够做出符合真实数据分布的最优决策,建议定期执行 ANALYZE 命令以刷新表的物理统计信息(参见 Chapter 14)。
索引同样能够极大加速带有过滤条件的 UPDATE 与 DELETE 操作。此外,索引还被广泛应用于表连接查询:为作为连接匹配条件的字段建立索引,通常能显著降低多表关联的计算耗时。
在通用语法层面,PostgreSQL 的索引能够用于加速包含如下结构的 WHERE 或 JOIN 条件:
indexed-columnindexable-operatorcomparison-value
其中 indexed-column 代表建立索引的列或表达式;indexable-operator 代表该索引在对应字段上绑定的操作符类(operator class)所包含的可用运算符;而 comparison-value 则是任何不依赖基表行变量的稳定比较表达式。