真实面经题目 · 原创解析
数据库索引为什么能加速查询?
数据库索引能加速查询,是因为它用有序的数据结构把全表扫描变成定向查找,减少需要读取、比较和回表的数据量,并且可以利用有序性优化范围查询、排序和覆盖查询。
真实面经题目 · 原创解析
数据库索引能加速查询,是因为它用有序的数据结构把全表扫描变成定向查找,减少需要读取、比较和回表的数据量,并且可以利用有序性优化范围查询、排序和覆盖查询。
索引加速查询的本质是减少扫描范围和 I/O。没有索引时,数据库可能逐行判断条件;有索引后,可以通过 B+ 树、哈希等结构先定位候选范围,再读取少量记录。以常见 B+ 树索引为例,树高通常很低,查询从根节点逐层定位到叶子节点,叶子节点有序并通过链表相连,所以适合等值查询、范围查询和排序优化。覆盖索引还能直接从索引返回结果,避免回表。不过索引不是越多越好,它会增加写入维护和存储成本,低选择性或返回大量数据时也未必划算。
没有索引时,数据库为了判断某个条件是否成立,可能需要读取大量记录并逐行比较,这就是全表扫描。索引相当于提前维护好的查找目录,查询时先在目录中定位满足条件的键值范围,再访问对应记录。它不会减少表中的总数据量,但能显著减少参与判断的数据量。
关系型数据库常见索引结构是 B+ 树。非叶子节点保存键值和指针,叶子节点保存键值以及数据定位信息。因为一个页能容纳很多键,B+ 树的分支因子很大,树高通常较低,几次页访问就能定位到目标范围。相比逐行扫描大量数据,这种访问路径更适合磁盘和缓存模型。
索引不只服务等值查询,还能利用键值有序的特点处理范围查询、排序、分组和去重。例如按时间范围查询时,可以定位起点后沿叶子层继续扫描;如果查询的排序方向和索引顺序匹配,数据库可能不需要额外排序,从而减少 CPU、内存和临时文件开销。
如果查询需要的列都包含在某个索引里,数据库可以只读取索引就返回结果,这叫覆盖索引。索引页通常比完整数据页更小,同样内存能缓存更多条目,访问也更集中。覆盖索引的收益不仅是命中条件更快,还包括避免根据主键或行地址再次读取完整数据行。
索引能加速查询不代表每次都会被使用。优化器会估算选择性、返回行数、回表成本、排序成本和统计信息。如果某个条件命中大部分数据,走索引再回表可能比顺序扫描更慢。理解索引加速的关键,是明白它优化的是访问路径,而访问路径是否划算取决于数据分布。
B+ 树分支因子大、树高低,更适合按页读取,可以减少随机 I/O。普通二叉树层数可能很高,每比较一次都可能带来一次页面访问,不适合大规模磁盘数据。
哈希索引通过哈希值定位,适合等值匹配,但哈希值不保留原始键的大小顺序。因此大于、小于、between、order by 这类依赖顺序的操作无法高效利用普通哈希索引。
要看查询模式。单独给性别、布尔状态这类字段建索引通常收益有限,但如果和时间、用户等字段组成联合索引,并符合高频查询前缀,仍可能有价值。
可能是索引选择性差、回表太多、联合索引顺序不合适、统计信息不准确、返回数据量过大,或者排序和分页成本很高。索引只是访问路径的一部分,不保证整体查询一定快。