MySQL中会用到age字段的索引_MySQL学习笔记(四):正确使用索引(二)
上一篇学习到了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学习笔记(四):正确使用索引(二)相关推荐
- mysql新增表字段回滚_MySql学习笔记四
MySql学习笔记四 5.3.数据类型 数值型 整型 小数 定点数 浮点数 字符型 较短的文本:char, varchar 较长的文本:text, blob(较长的二进制数据) 日期型 原则:所选择类 ...
- mysql原生建立索引_MySQL学习笔记之索引
索引是存储引擎用于快速找到记录的一种数据结构. 索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.在数据量较小且负载较低时,不恰当的索引对性能的影响可能还不明显,但 ...
- mysql 存储引擎的选择_MySQL学习笔记(四):存储引擎的选择
一:几种常用存储引擎汇总表 二:如何选择 一句话:除非需要InnoDB 不具备的特性,并且没有其他办法替代,否则都应该优先考虑InnoDB:或者,不需要InnoDB的特性,并且其他的引擎更加合适当前情 ...
- mysql删除不存在行数据报错_MySQL学习笔记11复制错误处理(二)删除不存在的行的问题...
(1)问题情况 在master上删除某个数据表的某一行,而该行在slave上并不存在,则slave上的复制过程会出错. MySQL的log文件中发现如下错误信息: 2017-08-15T04:52:1 ...
- mysql中利用sql语句修改字段名称,字段长度等操作(亲测)
在网站重构中,通常会进行数据结构的修改,所以添加,删除,增加mysql表的字段是难免的,有时为了方便,还会增加修改表或字段的注释,把同字段属性调整到一块儿.这些操作可以在phpmyadmin或者别的m ...
- Mysql中使用关键字name做字段名
今天在创建表时,创建name字段时,字段颜色不对,在运行时出现错误. 在网上搜后,就mysql中又说用"``" 把字段名括起来,有说用`()括起来,试了之后,发现都不是,要用 `n ...
- mysql中修改表字段名/字段长度/字段类型详解
在mysql中我们对数据表字段的修改命令只要使用alter就可以了,下面我来给大家详细介绍mysql中修改表字段名/字段长度/字段类型等等一些方法介绍,有需要了解的朋友可参考. 先来看看常用的方法 M ...
- mysql 如何把date转换数字_请教:mysql中,如何将date字段转换为int字段?
你的位置: 问答吧 -> 数据库 -> 问题详情 请教:mysql中,如何将date字段转换为int字段? 刚开始设计数据库时候,没有想到date类型只能精确到某一天,不能精确到秒. 现在 ...
- mysql 学习笔记--存储引擎、索引、sq优化
全面的 mysql学习笔记–通用语法.函数.数据类型.约束.多表查询.事务 全面的 mysql学习笔记–存储引擎.索引.sql优化 全面的mysql学习笔记–视图/存储过程/触发器.锁.InnoDB引 ...
最新文章
- switch case
- python自动修图_程序员不会用PS给女朋友修图?没关系,用Python十行代码轻松搞定-站长资讯中心...
- Thread.sleep() SystemClock.sleep()
- show in Breadcrumb
- 定时调度框架:Quartz.net
- RE正则表达式与grep
- 查看占用指定端口的程序
- 基于云的平台利用新技术来改变商店式购物营销
- 宝塔面板不能备份数据库,数据库备份大小20K,数据库备份报错mysqldump: Got error: 1045: Access denied for user 'root'@'localhost'
- python finally的作用_Python finally
- 读书笔记 - 《疯狂的站长》
- 激活出现 错误0x800706F7 占位程序接收到错误数据
- 洛谷 P1640 [SCOI2010]连续攻击游戏(二分图匹配)
- zuul - 微服务(十三)
- wps图表横纵坐标怎么设置_wps怎么切换横纵坐标/excel图表怎么切换横纵坐标
- iOS - 毛玻璃效果
- 蓝牙「5.0」和「4.2」的区别???
- Python函数复习
- SkiaSharp 之 WPF 自绘 拖曳小球(案例版)
- 安卓版微信 input onchange事件不生效