索引通过允许数据库更快地定位数据,从而提高查询性能,而无需扫描整个表。当数据库缺少用于查询的列的索引(例如 WHERE
子句)时,它必须执行全表扫描,检查每一行以查找匹配项。这很慢,尤其是对于大型表。索引就像一个排序的路线图,存储索引列的副本以及指向原始行的指针。例如,B 树索引以分层结构组织数据,使数据库能够跳过不相关的行并直接跳转到相关数据。这减少了所需的磁盘读取次数和计算步骤。
一个实际的例子:假设一个 users
表有 100 万行,并且一个查询搜索 WHERE email = 'user@example.com'
。如果没有索引,数据库会扫描所有 100 万行。如果在 email
上使用 B 树索引,数据库会导航树的各个级别——从根开始,比较值以缩小搜索范围——直到找到确切的电子邮件。B 树的对数搜索时间意味着即使对于 100 万行,也可能只需要 3-4 步(因为 log2(1M) ≈ 20,但 B 树具有更大的节点扇出)。扫描 100 万行(线性时间)与几个索引步骤(对数时间)之间的这种差异解释了为什么索引可以极大地加快查询速度。
但是,索引并非没有代价。它们会消耗存储空间并在写入期间增加开销(例如,INSERT
, UPDATE
),因为数据库必须同时更新表和索引。索引对于在搜索条件或连接中经常使用的列以及数据具有高选择性(例如,唯一的电子邮件)时最有效。对于具有低选择性的列(例如,只有两个值的 gender
列),索引可能没有帮助。开发人员应该分析查询模式并权衡读取速度的提升与写入性能的成本。正确应用索引是优化数据库性能的基础工具。