目录

  • 索引的优缺点
  • 索引类型
    • 聚簇索引(主键索引)
    • 非聚簇索引(二级索引、辅助索引)
  • 索引匹配的原则
    • 最左匹配原则
  • 无法使用索引的场景
  • 索引创建的原则
  • 使不使用索引的依据到底是什么?
  • 参考

索引的优缺点

常见的索引结构有: B 树, B+树和 Hash。

  • 优点:加快数据的检索速度
  • 缺点:
    1. 创建索引和维护索引需要耗费许多时间:当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率。
    2. 占用物理存储空间 :索引需要使用物理文件存储,也会耗费一定空间。

索引类型

聚簇索引(主键索引)

聚簇索引即索引结构和数据一起存放的索引,结构为B+树。
InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。

聚簇索引结构如下:

非聚簇索引(二级索引、辅助索引)

在聚簇索引之上创建的索引称之为辅助索引(二次索引),辅助索引节点只包含索引列值和主键值,因此辅助索引访问数据总是需要二次查找(即:通过二次索引找到主键值后回到聚簇索引找到对应的数据行)。
辅助索引叶子节点存储的不再是行的物理位置,而是主键值。通过辅助索引首先找到的是主键值,再通过主键值找到数据行的数据页,再通过数据页中的Page Directory找到数据行。
Innodb辅助索引非叶子节点只有索引列(不含主键),叶子节点并不包含行记录的全部数据,叶子节点只包含索引列和相应行数据的聚簇索引键。

Innodb二级索引,索引列值全相同的情况下,节点按主键值排序。

二级索引结构如下:

索引匹配的原则

最左匹配原则

如果创建一个联合索引, 此索引的任何前缀都会用于查询, 例如:
(col1, col2, col3)这个联合索引的所有前缀就是(col1), (col1, col2), (col1, col2, col3), 包含这些列的查询都会启用索引查询.
其他所有不在最左前缀里的列都不会启用索引, 即使包含了联合索引里的部分列也不会使用索引. 即上述中的(col2), (col3), (col2, col3) 都不会启用索引去查询.
注意:(col1, col3)会启用(col1)的索引查询。

无法使用索引的场景

  1. 复合索引的情况下,查询条件不满足索引最左的原则
  2. Mysql估计使用索引比全表扫描慢
  3. 索引 不能是表达式(函数)的一部分
    只有独立的列能使用索引,如:SELECT * FROM table WHERE id -1 = 1000; 无法使用索引 因为索引 id-1 不为独立的列
  4. 负向查询(not , not in, not like, <>, != ,!>,!< ) 不会使用索引
  5. 以%开头的LIKE查询不能够利用B-tree索引
  6. 用or分割开的条件,or前条件有索引,or后的列没有索引

    因为or后面的条件没有索引,那么后面的查询肯定要进行全表扫描,在存在全表扫描的情况下,就没有必要多一次索引扫描增加IO访问。

索引创建的原则

  • 不要使用更新频繁的列作为主键,不适用多列主键(相当于联合索引)
  • 不要使用 UUID,MD5,HASH,字符串列作为主键(无法保证数据的顺序增长),容易导致页分裂及随机IO,影响插入的速度。推荐使用自增值作为主键。
  • 索引列的顺序:
    1. 区分度最高的放在联合索引的最左侧(区分度=列中不同值的数量/列的总行数)
    2. 尽量把字段长度小的列放在联合索引的最左侧(因为字段长度越小,一页能存储的数据量越大,IO 性能也就越好)
    3. 使用最频繁的列放到联合索引的左侧(这样可以比较少的建立一些索引)
  • 避免建立冗余索引和重复索引(增加了查询优化器生成执行计划的时间)
    冗余索引示例:index(a,b,c)、index(a,b)、index(a)
  • 对于频繁的查询优先考虑使用覆盖索引

覆盖索引:就是包含了所有查询字段 (where,select,ordery by,group by 包含的字段) 的索引
覆盖索引的好处:
避免 Innodb 表进行索引的二次查询: Innodb 是以聚集索引的顺序来存储的,对于 Innodb 来说,二级索引在叶子节点中所保存的是行的主键信息,如果是用二级索引查询数据的话,在查找到相应的键值后,还要通过主键进行二次查询才能获取我们真实所需要的数据。而在覆盖索引中,二级索引的键值中可以获取所有的数据,避免了对主键的二次查询 ,减少了 IO 操作,提升了查询效率。
可以把随机 IO 变成顺序 IO 加快查询效率: 由于覆盖索引是按键值的顺序存储的,对于 IO 密集型的范围查找来说,对比随机从磁盘读取每一行的数据 IO 要少的多,因此利用覆盖索引在访问时也可以把磁盘的随机读取的 IO 转变成索引查找的顺序 IO。

使不使用索引的依据到底是什么?

在满足了使用索引的条件下,是否使用索引取决于使用索引的成本。

此段摘抄自:MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!

MySQL中决定使不使用某个索引执行查询的依据很简单:就是成本够不够小。而不是是否在WHERE子句中用了IS NULL、IS NOT NULL、!=这些条件。

答案很简单:成本。对于使用二级索引进行查询来说,成本组成主要有两个方面:
1. 读取二级索引记录的成本
2. 将二级索引记录执行回表操作,也就是到聚簇索引中找到完整的用户记录的操作所付出的成本。

查询列不在二级索引时,要扫描的二级索引记录条数越多,那么需要执行的回表操作的次数也就越多,达到了某个比例时,使用二级索引执行查询的成本也就超过了全表扫描的成本(举一个极端的例子,比方说要扫描的全部的二级索引记录,那就要对每条记录执行一遍回表操作,自然不如直接扫描聚簇索引来的快)。

参考

  • 什么是索引?
  • 官方文档解释MySQL最左匹配(最左前缀)原则
  • MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!
  • MySQL优化指南
  • mysql 存在索引但不能使用索引的典型场景
  • 聚簇索引和非聚簇索引(通俗易懂 言简意赅)

MySQL优化(二):索引的类型、匹配原则、创建原则相关推荐

  1. mysql to days 索引_高性能mysql优化二之索引篇

    前言 为什么要使用索引?索引有什么用途呢?我的亲身经历,一个几千万数据的项目,我写了一条查询,没有用到索引,由于访问量比较大,瞬间网站就跪了,从此以后我写的每一条sql都会explain解析看是否用到 ...

  2. (一)MySQL优化之索引优化

    一.索引的概念 我们知道,在查询过程中,如果被查询的表没有索引,数据库会进行全表扫描,而如果添加了相应的索引,数据库会根据索引直接查找符合条件的数据.因此,索引的存在会大大提高查询效率.而索引其实就是 ...

  3. mysql优化和索引的使用

    文章归属:http://www.cnblogs.com/doudouxiaoye/p/5831449.html 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那 ...

  4. 深入浅出Mysql - 优化篇(索引)

    SQL优化 通过show status了解各种sql执行的频率 mysql> show status like 'Innodb_rows_%';+----------------------+- ...

  5. mysql优化和索引_mysql优化和索引

    表的优化 1.定长与变长分离 如 int,char(4),time核心且常用字段,建成定长,放在一张表: 而varchar,text,blob这种变长字段适合单放一张表,用主键与核心表关联. 2.常用 ...

  6. Mysql优化之索引优化

    创建表 CREATE TABLE staffs( id INT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(24) DEFAULT NULL COMMENT' ...

  7. mysql优化varchar索引_MySQL优化--概述以及索引优化分析

    一.MySQL概述 1.1.MySQL文件含义 通过如下命令查看 show variables like '%dir%'; MySQL文件位置及含义 名称 值 备注 basedir /usr/ 安装路 ...

  8. mysql优化之索引_mysql优化之索引

    概念: 在数据库中除了数据之外,还维护着满足特定查找算法的数据结构.这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引.通常使用B树以及变种B+树 ...

  9. 【Mysql优化】索引覆盖

    索引覆盖 是指 如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回行到磁盘再找数据.这种查询速度非常快,称为"索引覆盖",比平时的查询少一次到磁盘读数据的操作 ...

  10. Mysql优化——唯一索引和普通索引的选择

    问题:当一个字段同时满足唯一索引和普通索引的情况下,我们要如何抉择呢? 要弄清楚这个问题,我们首先要了解唯一索引和普通索引的实现原理,我们通过查询操作和更新操作分别来对比他们之间的区别 附带一提,普通 ...

最新文章

  1. PHP标记风格,编码规范
  2. python企业微信回调_python 微信企业号-回调模式接收微信端客户端发送消息并被动返回消息...
  3. ExtJS4.2学习(9)——MVC
  4. html两方框重叠透明,html – 边缘浏览器向透明div添加重叠的“边缘”
  5. react前端显示图片_在react里怎么引用图片
  6. Day-5: Python高级特性
  7. 速度提升2倍,超强悍CPU级骨干网络PP-LCNet出世!
  8. fs.readfile 显示html,javascript – 从fs.readFile获取数据
  9. 顶点计划家庭感情冲突问题讨论
  10. Python代码规范
  11. linux 源代码安装mysql5.5_linux下通过源码包安装MySql5.5
  12. LINUX C正确遍历environ
  13. 队列(链式存储结构)
  14. 一个RSS阅读器的开源 ---- 邀请您加入开发队伍
  15. 99%的游戏主播都在用什么录屏软件?
  16. chrome 内核CEF 编译和qt 封装(上)
  17. 如何区分网线是几类的_几类网线怎么区分
  18. java使用ffmpeg实现视频切割
  19. 无锡工艺技术计算机信息管理论文,无锡工艺职业技术学院05/06学年第一学期.doc...
  20. 中软防水坝 怎么卸载_卸载中软防水墙软件

热门文章

  1. 牛客挑战赛30 C 小G砍树 换根dp+组合
  2. P1290 欧几里德的游戏
  3. Codeforces Round #717 (Div. 2)
  4. P2564 [SCOI2009]生日礼物
  5. P5049 [NOIP2018 提高组] 旅行
  6. 牛客题霸 [ 最长递增子序列] C++题解/答案
  7. Codeforces Round #760 (Div. 3)
  8. 【学习笔记】Miller-Rabin(米勒-拉宾)素性测试,附常用表
  9. [LCT动态树] [NOI2014]魔法森林,[ZJOI2018]历史
  10. [USACO19JAN,Platinum]Train Tracking 2