最近作一些项目接口的优化工做,发现其中涉及到调整mysql语句的方面,接口速度是提高最高的,借机学习一下关于mysql索引方面的知识mysql
基本是 《高性能MYSQL》的第五章 - 《建立高性能索引》的阅读sql
以前关于索引的错误理解bash
建表以后把字段都设置为索引比较好服务器
只要建立了索引并使用这个字段,就能命中索引markdown
索引(在 MySQL 中也叫“键key”)是存储引擎快速找到记录的一种数据结构数据结构
因此能够把索引看作一本书的目录函数
mysql的索引是存储引擎决定的,分为B-tree索引和 哈希索引(hash index)性能
不一样的存储引擎对支持不一样的两种索引mysql索引
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='xxx表' 复制代码
咱们的项目中,存储引擎是 InnoDB , 它使用的是 B-tree 索引,因此本文只是按照Btree来分享学习
减小服务器的扫描量
帮助服务器避免排序和临时表
随机IO变为顺序IO
三星原则:一星: 索引将相关的记录放到一块儿 二星:索引的数据顺序和查找的顺序一致 三星:索引的列包含查询中须要的所有列
独立的列: 不能是表达式的一部分,也不能是函数的参数
例: 筛选 area 字段是 beijing/beiJing/BeiJing 的数据
area已经在表里添加了索引
select * from TABLE where Upper(area) = 'BEIJING' 复制代码
若是是用函数处理了area字段
explain select * from TABLE where Upper(area) = 'BEIJING' 复制代码
能够看到是没法命中索引的
把where中的字段都设置为索引是最好的操做
其实这种状况下,可能达到了一星索引标准,比最优的索引差了不少
因此在须要对多个索引作相交操做(OR)/联合操做(AND) 的时候,能够考虑建立联合索引
这个是我的感受比较迷惑的一点,就是建立了联合索引以后,若是sql语句中的字段顺序与定义的不一致,那么有可能也没法使用索引
好比使用id和status定义复合索引
index (`id`,`status`)
复制代码
那么一下几种sql语句 并非都能使用索引的
select * from T where status = '23' // 索引失效 select * from T where id > 123 and status = '23' // 索引部分失效 复制代码
这个就是索引中的最左匹配原则
最左匹配原则: 索引首先按照最左列进行排序,其次第二列等等。因此索引可按照升序或者降序进行扫描,用以知足符合列顺序的order by / group by等查询需求
若有索引(a, b, c, d),查询条件a = 1 and b = 2 and c > 3 and d = 4,则会在每一个节点依次命中a、b、c,没法命中d
复制代码
频繁更新的字段
数据分布比较均匀的,好比,性别字段
表数据量少