上一篇学习到了MySQL中的索引是什么,以及一些关于索引的简单的知识,这篇我打算详细地谈一谈如何正确地使用索引。索引的使用看起来很简单,但是在真正去学习它的时候才发现,原来是暗藏玄机。使用索引时有很多需要特别注意的点,稍有不慎,我们建立的索引就不能发挥其作用了。

1、不是所有操作都能够使用到索引的。

比如在我们常用的查询操作中,,>=,BETWEEN,IN 是能够使用索引的,而 <>,NOT IN ,!= 则不行。

所以当我们希望在 NOT IN 和 != 操作中使用到索引,得把NOT IN 换成 NOT EXISTS,把 != 换成 id >5 OR id < 5。

以及在like中,用通配符%开头是不能使用索引的。

like '%mumu' 和 like '%mumu%'不能使用索引,而like 'mumu%' 和 like 'mumu' 能够使用。

所以,如果我们需要对大的文本进行搜索,一般有两种操作:

第一是使用全文索引FULLTEXT,但是会占用大量空间。

第二是使用前缀索引,即限制索引的大小,仅对字段的前N个字符设置索引,也能在很大程度上提升查询速度。

2、不是所有字段都适合用索引。

像状态、性别这种值重复率特别高的字段是不适合建立索引的,不仅会占用空间,还会造成不必要的性能损失。

另外,含有 NULL 的值不适合作为索引字段,索引不会包含有 NULL 值的列,尤其是在复合索引中,只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。(NULL这个家伙非常特殊,以后还得专门去学习一下)

3、索引的字段类型和查询的数据类型需要一致

比如说,你的字段 id 是 int 类型的,在建立了索引之后

select * from table where id=1; 是能够使用索引的,但是

select * from table where id="11"; 却不能使用索引

4、不能在添加了索引的字段上使用函数以及表达式(聚合函数除外)

聚合函数即 COUNT、SUM、AVG、MIN、MAX。

比如以下操作都是不能使用索引的。

select * from table where YEAR(time)=2020;

select * from table where id+1=5;

另外,在使用索引时,我们需要考虑索引的选择性,即不重复的索引值(基数)和数据表中的记总数的比值。索引的选择性越高则查询效率越高,因为选择性高的索引可以让MYSQL在查找时过滤掉更多的行。唯一索引和主键索引的选择性是1,这是最高的索引选择性,性能也是最好的。

为了更高的性能,还能将多个索引组合起来使用,即组合索引。组合索引会占用更多的空间,但是能够提高更高的效率。不过在使用组合索引的时候需要注意最左原则(之前说过的)。

仅仅是掌握以上的四种原则还远远不够,还有很多特殊的情况需要我们考虑。

1、在一个查询中,只能使用一个索引。其实与其说是只能使用一个索引,倒不如说同时使用两个单列索引的效率不如单单使用一个索引。数据库会根据 SQL 语句自己判断分析执行计划,选择最优的执行计划执行,即智能地选择是否使用索引,以及如何使用索引。

所以,在多个查询条件下,如果没有组合索引,数据库会自动选择一个最优的单列索引执行。

select * from table where id=1 and name='mumu' and age=20;

但是这是针对 AND 情况的,对 OR 条件并不适用。OR 会导致索引失效,即

//并不会使用到联合索引(id,name)

select * from table where id=1 or name='mumu';

所以如果我们希望 OR 也能够使用索引,就需要把 OR 换成相应的 IN、BETWEEN 和 UNION。

//比如把OR换成IN

select * from table where name in ('mm','mu','mumu');

//把OR换成BETWEEN

select * from table where age between (18,20);

//把OR换成UNION

select * from table where id=1;

union

select * from table where name='mumu';

2、ORDER BY 对索引的影响。在排序操作中,索引想要生效可不是那么容易。比如说,我建立了联合索引字段(name,age),那么以下的操作是能触发索引的:

//1 只查询索引字段

select name,age from table order by age;

//2 查询这两个索引字段加上别的已经建立了索引的字段

select id,name from table order by name,age;

//3 where和order的条件为同一个字段

select * from table where age=18 order by age;

//4 where和order使用了联合索引

select * from table where name='mumu' order by age;

//5 联合索引字段被where包含

select * from table where name='mumu' and age=18 order by age;

总结概括一下就是:ORDER BY 语句只有使用了跟 WHERE 语句中相同的索引字段(或组合索引),ORDER BY 中的索引才会生效。并且还需注意,当索引的顺序与ORDER BY中的列顺序不同,或者所有的列不是同一方向(全部升序或者全部降序)时,索引也不会生效。

覆盖索引与回表查询

覆盖索引,即所有需要查询的字段都被包含在了联合索引当中,在查询时只需要通过索引就能返回所需要的数据,而不再需要回表查询(如果我们需要的数据过多,并不是所有的字段都是索引,那么就需要去表中返回所需的数据),通过覆盖索引,能够极大极大地提升查询的效率,但是同时也会占用很多空间,使用时要谨慎。

关于 MySQL 的索引,真的还有很多东西要学,真正要学得通透还得深入到其中的数据结构和算法。不过更重要的还是学会去使用它。要想会用索引,可不是百度几下规则记一记就可以了,很多情况都是超出我们的预期的,我们应该学会使用 EXPLAIN,来具体地查看我们的语句有没有正确地使用到索引,然后再一步步优化。

另外,如果你有兴趣,或者是有问题想要与我探讨,欢迎来访问我的博客:https:mu-mu.cn/blog

MySQL中会用到age字段的索引_MySQL学习笔记(四):正确使用索引(二)相关推荐

  1. mysql新增表字段回滚_MySql学习笔记四

    MySql学习笔记四 5.3.数据类型 数值型 整型 小数 定点数 浮点数 字符型 较短的文本:char, varchar 较长的文本:text, blob(较长的二进制数据) 日期型 原则:所选择类 ...

  2. mysql原生建立索引_MySQL学习笔记之索引

    索引是存储引擎用于快速找到记录的一种数据结构. 索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.在数据量较小且负载较低时,不恰当的索引对性能的影响可能还不明显,但 ...

  3. mysql 存储引擎的选择_MySQL学习笔记(四):存储引擎的选择

    一:几种常用存储引擎汇总表 二:如何选择 一句话:除非需要InnoDB 不具备的特性,并且没有其他办法替代,否则都应该优先考虑InnoDB:或者,不需要InnoDB的特性,并且其他的引擎更加合适当前情 ...

  4. mysql删除不存在行数据报错_MySQL学习笔记11复制错误处理(二)删除不存在的行的问题...

    (1)问题情况 在master上删除某个数据表的某一行,而该行在slave上并不存在,则slave上的复制过程会出错. MySQL的log文件中发现如下错误信息: 2017-08-15T04:52:1 ...

  5. mysql中利用sql语句修改字段名称,字段长度等操作(亲测)

    在网站重构中,通常会进行数据结构的修改,所以添加,删除,增加mysql表的字段是难免的,有时为了方便,还会增加修改表或字段的注释,把同字段属性调整到一块儿.这些操作可以在phpmyadmin或者别的m ...

  6. Mysql中使用关键字name做字段名

    今天在创建表时,创建name字段时,字段颜色不对,在运行时出现错误. 在网上搜后,就mysql中又说用"``" 把字段名括起来,有说用`()括起来,试了之后,发现都不是,要用 `n ...

  7. mysql中修改表字段名/字段长度/字段类型详解

    在mysql中我们对数据表字段的修改命令只要使用alter就可以了,下面我来给大家详细介绍mysql中修改表字段名/字段长度/字段类型等等一些方法介绍,有需要了解的朋友可参考. 先来看看常用的方法 M ...

  8. mysql 如何把date转换数字_请教:mysql中,如何将date字段转换为int字段?

    你的位置: 问答吧 -> 数据库 -> 问题详情 请教:mysql中,如何将date字段转换为int字段? 刚开始设计数据库时候,没有想到date类型只能精确到某一天,不能精确到秒. 现在 ...

  9. mysql 学习笔记--存储引擎、索引、sq优化

    全面的 mysql学习笔记–通用语法.函数.数据类型.约束.多表查询.事务 全面的 mysql学习笔记–存储引擎.索引.sql优化 全面的mysql学习笔记–视图/存储过程/触发器.锁.InnoDB引 ...

最新文章

  1. switch case
  2. python自动修图_程序员不会用PS给女朋友修图?没关系,用Python十行代码轻松搞定-站长资讯中心...
  3. Thread.sleep() SystemClock.sleep()
  4. show in Breadcrumb
  5. 定时调度框架:Quartz.net
  6. RE正则表达式与grep
  7. 查看占用指定端口的程序
  8. 基于云的平台利用新技术来改变商店式购物营销
  9. 宝塔面板不能备份数据库,数据库备份大小20K,数据库备份报错mysqldump: Got error: 1045: Access denied for user 'root'@'localhost'
  10. python finally的作用_Python finally
  11. 读书笔记 - 《疯狂的站长》
  12. 激活出现 错误0x800706F7 占位程序接收到错误数据
  13. 洛谷 P1640 [SCOI2010]连续攻击游戏(二分图匹配)
  14. zuul - 微服务(十三)
  15. wps图表横纵坐标怎么设置_wps怎么切换横纵坐标/excel图表怎么切换横纵坐标
  16. iOS - 毛玻璃效果
  17. 蓝牙「5.0」和「4.2」的区别???
  18. Python函数复习
  19. SkiaSharp 之 WPF 自绘 拖曳小球(案例版)
  20. 安卓版微信 input onchange事件不生效

热门文章

  1. 关于协方差矩阵的理解
  2. Leetcode120.三角形的最小路径和 -- DP算法
  3. 伴随矩阵,可逆矩阵相关思路分析之一
  4. B-树关键字个数计算
  5. 二叉树插入算法的非递归版本
  6. c++ vector使用方法收集
  7. 使用 Gogs 搭建自己的 Git 服务器
  8. MySql基础笔记(三)其他重要的事情
  9. 诡异的json包含bom头
  10. canvas浅谈 实现简单的自旋转下落