询问任何一位经验丰富的数据库管理员,哪一个单一的改变最能可靠地提升查询性能,答案几乎总是相同的:那就是更好的索引。然而,索引也是数据库开发人员工具库中最容易被误解的工具之一。许多开发人员是被动地添加索引,犹豫不决地删除索引,并且仅仅因为不确定其他选择而错误地选择了某种类型的索引。本指南将详细介绍最重要的索引类型——B-tree索引、哈希索引、部分索引和复合索引,解释每一种索引何时适用,并展示 Navicat 的表设计器如何简化索引的创建和管理。
为何索引如此重要
索引是一种独立的数据结构,数据库会将其与表一同维护。其设计初衷是为了在无需扫描每一行的情况下实现特定的查找操作。如果没有针对经常查询的列设置索引,数据库每次查询都会进行全表扫描。对于几千行数据来说,这种操作还算可以接受,但当数据量达到数百万时,这个过程就会变得极其缓慢。其代价在于,每个索引都会增加写操作的开销,因为插入、更新和删除操作不仅需要更新表数据,还需要更新索引。明智地选择索引(而非随意设置)是区分优化良好的模式和读取速度快但写入速度慢的模式的关键所在。
B-Tree索引:明智的默认设置
B-Tree(平衡树)索引是大多数数据库在未进行任何其他设置的情况下所创建的索引,这是有充分理由的。它将值存储在一种有序的层次结构中,这种结构使其适用于精确匹配、范围查询以及排序操作等各类操作。如果你的查询包含一个与某个列进行比较的 WHERE 子句(例如使用 =、<、>、BETWEEN 或 LIKE ‘prefix%’),那么在该列上创建 B-Tree索引几乎肯定是正确的选择。
初学者常常会忽略的一点是,B-Tree索引还支持排序功能。如果你的查询是按照某个索引列来对结果进行排序的,那么数据库可以按照索引列的顺序读取索引信息,而不是对整个结果集进行排序,这对于处理大型表来说能带来显著的性能提升。
哈希索引:快速但范围有限
哈希索引会存储每个列值的计算哈希值,而非其实际值。这使得它们在进行精确匹配查找时速度极快;数据库会计算你搜索项的哈希值,并直接跳转到匹配的条目。但其缺点是,哈希索引不适用于范围查询或排序,因为哈希值没有有意义的顺序。此外,它们也不支持多列查找。
哈希索引最适合那些仅通过“=”进行查询且值差异极大的列,例如 UUID 或会话令牌。在 MySQL 中,哈希索引仅适用于 MEMORY 表;而在 PostgreSQL 中,它们是常规表的完全支持选项,并且在最近的版本中其功能也变得越来越强大。
部分索引:仅对查询的内容进行索引
部分索引(在 SQL Server 中也被称为过滤索引)是基于由某个条件所定义的一组特定行而构建的。例如,如果你的订单表有数百万行数据,但你的应用程序几乎只针对状态为“待处理”的订单进行查询,那么在“状态”列上创建一个条件为 status = ‘pending’ ( “状态 = ‘待处理’”)的部分索引将会比在该列上创建一个完整索引要小且更快。
部分索引对于“软删除”模式尤其有用,在这种模式下,大量行被标记为已删除且很少被查询到。将这些行从索引中排除出去可以使索引保持简洁,并让查询规划器更加满意。PostgreSQL 提供了对部分索引的原生支持;SQL Server 则通过筛选索引来实现相同的效果,其语义几乎完全相同。
综合指数:列顺序至关重要
复合索引会跨越多个列,如果设计得当,它能够满足复杂的多列查询需求,而无需数据库直接访问底层表。需要牢记的关键原则是:复合索引只能从左向右使用。例如,建立(姓氏,名字)的索引将有助于根据姓氏进行查询筛选,或者根据姓氏和名字一起进行查询筛选,但不会有助于仅根据名字进行查询筛选。
在创建复合索引时,排列列的通用规则是将最具有选择性的列放在首位,即能删除最多数据行的列。在等式条件(=)中使用的列应排在范围条件(>、<、 BETWEEN)之前,因为索引中某个位置的范围条件会妨碍优化器有效地利用索引中的后续列。
使用 Navicat 的表设计器管理索引
Navicat 的表设计器 为创建和管理上述所有索引类型提供了一个实用且直观的环境,无需手动编写 DDL 代码。索引的操作在设计器中的“索引”选项卡上进行,该选项卡与用于定义列的“字段”选项卡是分开的。这种分离使得能够一眼就清晰地查看表的索引策略。
要添加索引,你需要为其指定一个名称,选择它应涵盖的列(或列组),然后从下拉菜单中选择索引类型和方法。至关重要的是,这些下拉菜单中的可用选项是根据你所连接的特定数据库而定制的。如果你在使用 MySQL,你将会看到 MySQL 支持的索引类型;切换到 PostgreSQL 连接,选项则反映了 PostgreSQL 的功能,包括 B-Tree、哈希、GIN、GiST 等等。这种基于上下文的特性意味着你不会被要求猜测哪些选项适用于你目标的数据库。
对于复合索引,你可以将多个字段添加到单个索引条目中,并对其进行重新排序以符合你期望的列优先级顺序——正如上文所述,这直接影响索引是否以及如何被使用。主键列会在“字段”选项卡中可见,并且它们会被明确标注出来,而所有二级索引则位于“索引”选项卡中。
结语
良好的索引设置并非在于增加更多的索引,而在于添加恰当的索引。B-tree索引适用于绝大多数日常查询模式;哈希索引在精确匹配的狭窄场景中占据一席之地;部分索引在你仅查询数据子集的情况下能保持简洁;而复合索引若排序得当,能够一次性完成多个单列索引的功能。理解这些区别,并利用像 Navicat 的表设计器这样的工具来高效地实现和验证它们,将使你在数据量增加时能够保持查询速度。

