当数据量越来越大,索引对性能的影响愈发重要,在数据较小且负载较低时,不恰当的索引对性能的影响可能还不明显,但当数据量增大时,性能则会急剧下降。
5.1 索引基础
索引就像一本书的目录,帮助我们快速找到对应的页码。在MySQL中,存储引擎用类似的方法使用索引,其现在索引中找到对应值,然后根据匹配的索引记录找到对应的数据行。假如要运行下面的查询:
mysql> SELECT first_name FROM sakila.actor WHERE actor_id =5;
如果在actor_id列上建有索引,则MySQL将使用该索引找到actor_id为5的行,也就是说,MySQL先在索引上按键进行查找,然后返回所有包含该值数据行。
索引可以宝行一个或多个列的值。如果索引包含多个列,那么列的顺序也非常重要,因为MySQL只能高效的使用索引的最左前缀列。创建一个包含两个列的索引,和创建两个只包含一列的索引大不相同。
使用ORM还用关心索引吗?
是的,即使是使用对象关系映射(ORM)工具。
除非只是非常基本的查询(例如仅仅是根据主键查询),否则它很难生成适合索引的查询。即使是查询优化技术专家也很难兼顾到各种情况,更别说ORM了。
5.1.1 索引的类型
索引有多种类型,为不同的场景提供更好的性能。在MySQL中,索引是在存储引擎层而不是服务器层实现的。所以,没有统一的索引标准;不同存储引擎的索引的工作方式也不一样,不是所有的存储引擎支持所有类型的索引。即使多个存储引擎支持同一种类型的索引,其底层的实现也可能不同。B-Tree索引
平常说的B树,就是B-树(不是B+树)。平常说的索引,如果没有指明类型的话,多半指的是B-Tree索引,它使用B-Tree数据结构来存储数据。大多数MySQL引擎都支持这种索引。Archive引擎是一个例外;5.1之前Archive不支持任何索引,知道5.1才开始支持单个自增列(AUTO_INCREMENT)的索引。
我们使用术语“B-Tree”,是因为MySQL在CREATE 和其他语句也使用该关键字。不过底层的存储引擎也使用不同的存储结构,例如NDB集群存储引擎内部实际使用T-Tree结构来存储这种索引,InnoDB则使用的是B+Tree。
存储引擎以不同的方式使用B-Tree索引,性能也各有不同,各有优势。例如,MyISAM使用前缀压缩技术使得索引更小,但InnoDB则按照原数据格式进行存储。再如 MyISAM索引通过数据的物理位置引用被索引的行,而InnoDB则根据主键引用被索引的行。
参考资料
《高性能MySQL第三版》