索引是什么?
MySQL官方对索引的定义为:索引是帮助MySQL高效获取数据的数据结构;
索引是提高查询速度的最重要的工具,虽然还有一些其他技术能提升性能,但一般来说引起最大性能差异的,都是索引的正确使用,所以应该首先从索引的角度来提升性能;
MySQL索引类型
普通索引(INDEX),最基本的索引,没有任何限制;
唯一索引(UNIQUE),值必须是唯一,但允许空;
主键索引(PRIMARY KEY),是一种特殊的唯一索引,不允许有空值;
全文索引(FULLTEXT),仅可用于MyISAM,检索文本信息用,针对较大的数据,生成时耗时耗空间;
单列索引:一个索引只包含一个列,注意,多个单列索引之间没有任何关系;
多列索引(组合索引):一个索引包含多各列,尤其需要注意的是创建组合索引时各列的顺序;
MySQL索引方法——BTree
BTree索引:MySQL数据库中使用最频繁的索引类型,基本所有存储引擎都支持BTree索引,下图分别是MyISAM和InnoDB存储引擎的BTree索引。
MySQL索引方法——Hash
Hash索引:主要通过Hash算法(常见的Hash算法有直接定址法、平方取中法、折叠法、除数取余法、随机数法),将数据库字段数据转换成定长的Hash值,与这条数据的行指针一并存入Hash表的对应位置;如果发生Hash碰撞(两个不同关键字的Hash值相同),则在对应Hash键下以链表形式存储。
检索算法:在检索查询时,就再次对待查关键字再次执行相同的Hash算法,得到Hash值,到对应Hash表对应位置取出数据即可,如果发生Hash碰撞,则需要在取值时进行筛选。目前使用Hash索引的数据库并不多,主要有Memory等。
一般来说,索引的检索效率非常高,可以一次定位,不像B-Tree索引需要进行从根节点到叶节点的多次IO操作。有利必有弊,Hash算法在索引的应用也有很多弊端,例如:
a、Hash索引仅仅能满足等值的查询,范围查询不保证结果正确。因为数据在经过Hash算法后,其大小关系就可能发生变化。
b、Hash索引不能被排序。同样是因为数据经过Hash算法后,大小关系就可能发生变化,排序是没有意义的。
c、Hash索引不能避免表数据的扫描。因为发生Hash碰撞时,仅仅比较Hash值是不够的,需要比较实际的值以判定是否符合要求。
d、Hash索引在发生大量Hash值相同的情况时性能不一定比B-Tree索引高。因为碰撞情况会导致多次的表数据的扫描,造成整体性能的低下,可以通过采用合适的Hash算法一定程度解决这个问题。
e、Hash索引不能使用部分索引键查询。因为当使用组合索引情况时,是把多个数据库列数据合并后再计算Hash值,所以对单独列数据计算Hash值是没有意义的。
索引的优缺点
索引的优点是可以提高检索数据的速度,这是创建索引的最主要的原因;对于有依赖关系的子表和父表之间的联合查询时,可以显著提高查询速度;使用分组和排序子句进行数据查询时,同样可以显著节省查询中分组和排序的时间。
索引的缺点是创建和维护索引需要耗费时间,耗费时间的数量随着数据量的增加而增加;每一个索引要占一定的物理空间;增加、删除和修改数据时,要动态的维护索引,造成数据的维护速度降低了。
各种索引的适用场景
索引的本质:以空间换时间,以插入更新速度降低换取查询检索速度的提升。
主键索引/唯一索引:以更快的速度精准的定位到某条数数据,适用于绝大多数需要更新和查询的表(只会插入数据的表除外),绝对用不到范围查询的可以使用Hash索引;
普通索引/组合索引:表的关联、查询,适用于查询需求较多的表,对经常插入和更新的表要适当降低组合索引的使用;
全文索引:全文检索使用,但如果有的选择,尽量不用数据库自己的全文索引。
Hash索引:主键,MD5码等需要唯一确定一条数据的等值查询,需要范围查询的不能使用Hash索引;