Mysql索引,哪些状况下数据库索引会失效

MySQL索引的概念

索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里全部记录的引用指针。更通俗的说,数据库索引比如是一本书前面的目录,能加快数据库的查询速度。mysql

索引的分类

注意:索引是在存储引擎中实现的,也就是说不一样的存储引擎,会使用不一样的索引sql

MyISAM和InnoDB存储引擎:只支持BTREE索引, 也就是说默认使用BTREE,不可以更换数据库

MEMORY/HEAP存储引擎:支持HASH和BTREE索引缓存

mysql的索引分为单列索引(主键索引,惟索引,普通索引)和组合索引.性能

单列索引:一个索引只包含一个列,一个表能够有多个单列索引.
组合索引:一个组合索引包含两个或两个以上的列,mysql索引

1. 普通索引

这是最基本的索引,它没有任何限制,好比上文中为title字段建立的索引就是一个普通索引,MyIASM中默认的BTREE类型的索引,也是咱们大多数状况下用到的索引。spa

2. 惟一索引

与普通索引相似,不一样的就是:索引列的值必须惟一,但容许有空值(注意和主键不一样)。若是是组合索引,则列值的组合必须惟一,建立方法和普通索引相似。指针

3. 全文索引(FULLTEXT)

MySQL从3.23.23版开始支持全文索引和全文检索,FULLTEXT索引仅可用于 MyISAM 表;他们能够从CHAR、VARCHAR或TEXT列中做为CREATE TABLE语句的一部分被建立,或是随后使用ALTER TABLE 或CREATE INDEX被添加。////对于较大的数据集,将你的资料输入一个没有FULLTEXT索引的表中,而后建立索引,其速度比把资料输入现有FULLTEXT索引的速度更为快。不过切记对于大容量的数据表,生成全文索引是一个很是消耗时间很是消耗硬盘空间的作法。code

4. 单列索引、多列索引

多个单列索引与单个多列索引的查询效果不一样,由于执行查询时,MySQL只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。blog

5. 组合索引(最左前缀)

平时用的SQL查询语句通常都有比较多的限制条件,因此为了进一步榨取MySQL的效率,就要考虑创建组合索引。例如上表中针对title和time创建一个组合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。创建这样的组合索引,实际上是至关于分别创建了下面两组组合索引:
–title,time
–title
为何没有time这样的组合索引呢?这是由于MySQL组合索引“最左前缀”的结果。简单的理解就是只从最左面的开始组合。并非只要包含这两列的查询都会用到该组合索引

CREATE INDEX nickname_account_createdTime_Index ON `award`(`nickname`, `account`, `created_time`);

使用索引须要注意的地方

在创建索引的时候应该考虑索引应该创建在数据库表中的某些列上面 哪一些索引须要创建,哪一些因此是多余的.
通常来讲,
1.在常常须要搜索的列上,能够加快索引的速度
2.主键列上能够确保列的惟一性
3.在表与表的而链接条件上加上索引,能够加快链接查询的速度
4.在常常须要排序(order by),分组(group by)和的distinct 列上加索引 能够加快排序查询的时间,  (单独order by 用不了索引,索引考虑加where 或加limit)
5.在一些where 以后的 < <= > >= BETWEEN IN 以及某个状况下的like 创建字段的索引(B-TREE)
6.like语句的 若是你对nickname字段创建了一个索引.当查询的时候的语句是 nickname lick '%ABC%' 那么这个索引讲不会起到做用.而nickname lick 'ABC%' 那么将能够用到索引
7.索引不会包含NULL列,若是列中包含NULL值都将不会被包含在索引中,复合索引中若是有一列含有NULL值那么这个组合索引都将失效,通常须要给默认值0或者 ' '字符串
8.使用短索引,若是你的一个字段是Char(32)或者int(32),在建立索引的时候指定前缀长度 好比前10个字符 (前提是多数值是惟一的..)那么短索引能够提升查询速度,而且能够减小磁盘的空间,也能够减小I/0操做.
9.不要在列上进行运算,这样会使得mysql索引失效,也会进行全表扫描
10.选择越小的数据类型越好,由于一般越小的数据类型一般在磁盘,内存,cpu,缓存中 占用的空间不多,处理起来更快

什么状况下不建立索引

1.查询中不多使用到的列 不该该建立索引,若是创建了索引然而还会下降mysql的性能和增大了空间需求.
2.不多数据的列也不该该创建索引,好比 一个性别字段 0或者1,在查询中,结果集的数据占了表中数据行的比例比较大,mysql须要扫描的行数不少,增长索引,并不能提升效率
3.定义为text和image和bit数据类型的列不该该增长索引,
4.当表的修改(UPDATE,INSERT,DELETE)操做远远大于检索(SELECT)操做时不该该建立索引,这两个操做是互斥的关系

什么 状况下数据库索引会失效

1.若是条件中有or,即便其中有条件带索引也不会使用(这也是为何尽可能少用or的缘由)

注意:要想使用or,又想让索引生效,只能将or条件中的每一个列都加上索引

2.对于多列索引,不是使用的第一部分,则不会使用索引

3.like查询是以%开头

4.若是列类型是字符串,那必定要在条件中将数据使用引号引用起来,不然不使用索引

5.若是mysql估计使用全表扫描要比使用索引快,则不使用索引

查看索引的使用状况:

show status like ‘Handler_read%’;

注意: handler_read_key:这个值越高越好,越高表示使用索引查询到的次数 handler_read_rnd_next:这个值越高,说明查询低效