浅学 mysql 中的索引

最近作一些项目接口的优化工做,发现其中涉及到调整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等查询需求

  • mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就中止匹配,后面的索引就再也不处理,至关于后面的直接失效
若有索引(a, b, c, d),查询条件a = 1 and b = 2 and c > 3 and d = 4,则会在每一个节点依次命中a、b、c,没法命中d
复制代码
  • =和in能够乱序,好比联合索引是 (a,b,c) ,那么 a = 1 and b = 2 and c = 3 能够任意改变顺序 ,由于mysql的查询优化器会帮你优化成索引能够识别的形式

不适合建立索引的状况

  • 频繁更新的字段

  • 数据分布比较均匀的,好比,性别字段

  • 表数据量少

相关文章
相关标签/搜索