# 索引的优点

索引可以让服务器快速定位到表的指定位置。但是这并不是索引的唯一作用,到目前为止可以看到,根据创建索引的数据结构不同,索引也有一些其他的附加作用。

最常见的 B-Tree 索引,按照顺序存储数据,所以 MySQL 可以用来做 order byt 和 group by 操作。因为数据是有序的,所以相关的列值都存储在一起。最后,因为索引中存储了实际的列值,所以某些查询只使用索引就能够完成全部查询。据此特性,总结有如下三个优点:

  1. 索引大大减少了服务器需要扫描的数据量
  2. 索引可以帮助服务器避免排序和临时表。
  3. 索引可以将随机 I/O 变为顺序 I/O。

索引这个主题值得完全单独写一本书,如果想深入理解,强烈建议阅读 《Relational Database Index Design and the Optimizers》,该书详细介绍了如何计算索引的成本和作用、如何评估查询速度、如何分析索引维护的代价和其他带来的好处等。

# 三星系统

在书中介绍如何评价 一个索引是否适合某个查询的「三星系统」

  • 索引将相关的记录放到一起,获得一星
  • 如果索引中的数据顺序和查找中的排列顺序一致则获得二星
  • 如果索引中的列包含了查询中需要的全部列则获得三星。

后续还需继续介绍这些原则。

# 索引是最好的解决方案吗?

索引并不总是最好的工具。总的来说,只有当所有帮助存储引擎快速找到记录带来的好处大于其他来带的额外工作时,索引才是最有效的。

  • 非常小的表:大部分情况下,简单全表扫描更高效
  • 中到大型表:索引就非常有效
  • 特大型表:建立和使用索引的代价随之增长,这种情况下,需要一种技术可以直接区分出查询需要的一组数据,而不是一条一条记录匹配。例如可以使用分区技术,请参考第 7 章

如果表的数量特别多,可以建立一个元 数据信息,用来查询需要用到的某些特性。

例如:执行那些需要聚合多个应用分布在多个表的数据的查询,则需要记录「哪个用户的信息存储在哪个表中」的元数据,这样在查询时就可以直接忽略那些不包含指定用户信息的表。

对于大型系统来说,这是一个常用的技巧。事实上, infobright 就是使用类似的实现,对于 TB 级的数据,定位单条记录的意义不大,所以经常会使用快级别元数据技术来替代索引。