mysql索引
1. 索引是什么
索引其实也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
2. 索引的好处:
创建索引可以大大提高系统的性能。
- 加快mysql的检索速度,这也是建立索引的主要原因;
- 通过创建唯一性索引,可以保证数据库中每条记录的唯一性;
- 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义;
- 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间;
- 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
3. 索引的坏处:
- 降低更新表的速度,因为对表进行insert、update、delete时,mysql不仅要保存数据,还要更新索引文件;
- 建立索引会占用磁盘空间的索引文件,一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会增长很快。
4. 索引的分类:
普通索引:分为单列索引和组合索引,单列索引,即一个索引只包含一个列,多列索引,即一个索引包含多个列;
唯一索引:索引列的值必须唯一,但允许有空值,如果是组合索引,则列值得组合必须唯一;
主键索引:一个表的主键就是一种特殊的唯一索引,不能有控制,一个表只能有一个主键;
-
组合索引:指在多个字段上创建的索引,只有在查询条件中使用了创建组合索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合。
最左前缀: 定义:最左前缀原则指的的是在sql where 子句中一些条件或表达式中出现的列的顺序要保持和多索引的一致或以多列索引顺序出现,只要 出现非顺序出现、断层都无法利用到多列索引。 举例说明:加入有一个多列索引(username,password,age),当三列在where中出现的顺序如(username,password,age)、 (username,password)、(username)才能用到索引,如下面几个顺序(password,age)、(passwrod)、(age),这三者不 从username开始;(username,age),出现断层,少了password,都无法利用到索引。因为B+tree多列索引保存的顺序是按照索引创建的顺序,检索索引时按照此顺序检索。
全文索引:主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。fulltext索引配合match against操作使用,而不是一般的where语句加like。它可以在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上可以创建全文索引。值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用CREATE index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多。
-- 全文索引查询的例子
select * from books where match(title,content) against('java');
5. 哪些情况不适合加索引
- 对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
- 对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
- 对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
- 当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。
- 如果每次都需要取表的所有记录;
- 对于记录比较少的表。
6. 索引的数据结构
InnoDB和MyISAM数据存储引擎中使用B+树来保存索引,但是这两种引擎的实现方式不同。
InnoDB存储引擎支持以下几种索引:
- B+ 树索引;
- 全文索引
- 哈希索引
InnoDB支持的哈希索引是自适应的,会根据表的使用情况自动为表生成哈希索引,不能人为干预是否在一张表中生成哈希索引。InnoDB存储引擎会监控对表上各索引页的查询,如果观察到哈希索引可以带来速度提升,则建立哈希索引,称之为自适应哈希索引。
B+树索引并不能找到一个给定键值得具体行,B+树索引能找到的只是被查找数据行所在的页,然后数据库通过把页读入内存,再在内存中进行查找,最后得到想要查找的数据。
参考:
《MySQL技术内幕》