避免索引失效原则(二)

注:继上一篇文章继续讲解:

避免索引失效原则(一)https://www.cnblogs.com/StanleyBlogs/p/10482048.html#4195062

作者 : Stanley 罗昊

转载请注明出处和署名,谢谢!

体验SQL优化中的概率情况

在上一篇文章结尾处,我们在执行查询计划的时候,却发现我明明加了索引,并且也满足了使用索引的条件,但是,给我的优化结果却是失败,从而,得出一个结论便是,优化是概率的,也就跟彩票一样,不可能百分之百优化成功的,但是彩票我们都知道,全凭运气,但是这里就不一样了,我们需要了解SQL优化概率背后到底是谁导致它优化失败的;

首先,我们来了解下,出现概率优化的原因:因为在SQL底层中,有一个服务层,服务层有一个SQL优化器,当我们写一条语句,虽然我们手动优化了,但是,优化器觉得你优化的不太合适,它可能会进行一些自己的干扰,干扰完毕之后就执行结果就不再是你理想中的那样了,所以这个优化器有的时候会阻扰我们的优化工作;

接下来,我们就通过几个例子来体验一下我们设想的优化和实际不一样的一些操作;

首先,我们需要建立一个复合索引:

alter table book add index idx_book_at(authorid,typeid);

建立完索引后,我们进行一个简单的查询:

explain select * from book where authorid = 1 and typeid = 2;

通过结果我们可以发现,复合索引全部生效了

那么接下来,我们将体验一下让它产生概率问题,我把上面的SQL语句拿过来改改:

explain select * from book where authorid > 1 and typeid = 2;

我们查看执行结果:

结果很明显,给authorid 添加了一个大于号,这样则导致了右侧索引全部失效,包括自身,从而得出一个结论,复合索引中如果有>,则自身已经后面的索引都将会失效;

但是,这次我SQL语句再次改变,奇怪的事情将会发生:

explain select * from book where authorid = 1 and typeid > 2;

这次我把这个大于号加给了typeid字段,显然它也是索引,刚才我说了,添加大于号会导致自身并且右侧索引全部失效,但是接下来:

现在我们又发现,结论又不对了,我明明自身肯定失效啊,为啥这次偏偏却两个都生效了?

原因就是概率情况,咱们在实际执行时,复合索引全部使用了,并不是刚才我们说的那个结论,自身失效及右侧全部失效,当然,这个情况是大部分情况下都是有用了,仅有小部分情况会出现;

明显的概率问题

刚才我写了几个例子看起来不是特别的明显,下面我将写几个比较明显的例子来体验一下概率问题;

首先,我们编写一条SQL语句:

explain select * from book where authorid < 1 and typeid = 2;

此时,我把authorid改成了小于号,我们看结果:

我们看到了,此时,我们换层了小于号,发现没有全部失效,此条语句得出结论,两个索引,仅生效了一个因为范围查询仅对自身生效,对后面的不会生效

接下来,我再改变一下SQL语句:

explain select * from book where authorid < 4 and typeid = 2;

首先看清楚,我现在没有更改任何符号,仅把authorid小于号后面的数字条件写成了4,再来看看执行结果:

我们惊奇的发现,竟然全部失效了,我明明就光改了一个数字而已,就全部失效了,刚才还有一个生效,现在一个都没有了,这到底是为什么呢?

通过后两个例子我们发现,就改了一个数,索引都不一样了,所以,这就是SQL优化的一个概率;

因此得出结论,我们学习的索引优化,是一个大部分情况都适用的结论,但由于SQL优化器等原因,该结论不是100%正确,因为SQL的底层把我们写的语句给干扰了;

一般而言,范围查询(> < in),之后的索引失效,仅对自身生效;

补救

那么,如果这样一直干扰下去,我们到底还优不优化了?就没有办法来补救这个概率问题吗?答案是有的;

尽量使用索引覆盖 (using index)在Extra里面出现这个,就表示你的SQL语句不会出错,如果你怕在优化中出现概率问题,那么你就朝着using index这个方向去优化,因为,出现这个就代表你这条SQL100%生效,不会出现概率问题;

比如我现在有 a b c三张表;

现在我编写一条SQL,select a,b,c from 表名 where a = ... and b = ...;

在select后面我们用到了abc 并且查询条件也是a b 没有跨列,满足最佳做前缀,最主要的是查询条件也是索引,所有的索引你都按照规则全部用上了,这样就会出现索引覆盖,大大的提高了系统性能;

like尽量以“常量”开头,不要以'%'开头,否则索引失效

我现在编写一条SQL语句;

select * from 表名 where name like '%x%';

首先,这条sql语句是查询表名中name 带有x的数据,如果你这样写了,如果name是索引,那么name将会失效!

接下来,我结合数据库进行证实一下;

explain select tname  from teacher where tname like '%x%'

首先,tname我是加了一个索引的,但是看一下看一下执行结果:

没有失效,因为出现了覆盖索引,因为tname是索引,我刚好去查tname,所以出现了覆盖索引,导致本次查询没有失效,下面我把它换成“*”;

值得注意的是,在开发过程中,严禁出现“*”!本次为了说明问题,所以换成“*”;

执行结果:

索引全部失效!原因我刚才也说过了,在模糊查询是,不要以百分号开头;

如果想避免失效,可以变成以下这种写法:

explain select tname  from teacher where tname like 'x%'

这样虽然可以保证索引不会失效,但是,我们在项目开发中,难免遇到模糊查询,所以也是有解决方案的;

刚才我不小心也试出来了,因为我使用了索引覆盖,你想用模糊查询可以,但是你需要有索引覆盖,刚才我查询tname,tname本身就在索引里面,所以出现了索引覆盖;

如果必须使用模糊查询,那么就把查询条件以及需要查询的字段全部声明成索引即可;

尽量不要使用类型转换(显示、隐式),否则索引失效

这里我就简单的举个例子:

select * from teacher where tname = 'abc';

此时,tname是varchar类型,这个时候你你却写成int类型:

select * from teacher where tname = 123;

人家本来需要单引号的字符串类型,结果你给人家弄了一个去掉引号的int类型,所以索引就会失效;

尽量不要使用or,否则索引失效

select * from teacher where tname = " " or tcid>1;

这条sql语句就会导致索失效,所以要避免使用or这个关键字!

经过测试发现,or回导致以左的索引失效,也就是tname这个字段的索引失效了;

今日感悟:

努力就一定会有收获,心无旁骛

SQL优化 MySQL版 - 避免索引失效原则(二)的更多相关文章

  1. SQL优化 MySQL版 - 避免索引失效原则(一)

    避免索引失效原则(一) 精力有限,剩余的失效原则将会在 <避免索引失效原则(二)>中连载出来,请谅解 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 避免索引失效的一些原 ...

  2. SQL优化 MySQL版 - B树索引详讲

    SQL优化 MySQL版  - -B树索引详讲 作者:Stanley 罗昊 [转载请注明出处和署名,谢谢!] 为什么要进行SQL优化呢?很显然,当我们去写sql语句时: 1会发现性能低 2.执行时间太 ...

  3. SQL优化 MySQL版 - 索引分类、创建方式、删除索引、查看索引、SQL性能问题

    SQL优化 MySQL版  - 索引分类.创建方式.删除索引.查看索引.SQL性能问题 作者 Stanley 罗昊 [转载请注明出处和署名,谢谢!] 索引分类 单值索引 单的意思就是单列的值,比如说有 ...

  4. SQL优化 MySQL版 -分析explain SQL执行计划与笛卡尔积

    SQL优化 MySQL版 -分析explain SQL执行计划 作者 Stanley 罗昊 [转载请注明出处和署名,谢谢!] 首先我们先创建一个数据库,数据库中分别写三张表来存储数据; course: ...

  5. SQL优化 MySQL版 - 多表优化及细节详讲

    多表优化及细节详讲 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 注:本文章需要MySQL数据库优化基础或观看前几篇文章,传送门: B树索引详讲(初识SQL优化,认识索引):htt ...

  6. SQL优化 MySQL版 - 单表优化及细节详讲

    单表优化及细节详讲 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 注:本文章需要MySQL数据库优化基础或观看前几篇文章,传送门: B树索引详讲(初识SQL优化,认识索引):htt ...

  7. SQL优化 MySQL版 -分析explain SQL执行计划与Type级别详解

    type索引类型.类型 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 注:看此文章前,需要有一定的Mysql基础或观看上一篇文章,该文章传送门: https://www.cnblo ...

  8. SQL优化 MySQL版 -分析explain SQL执行计划与Extra

    Extra 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 注:此文章必须有一定的Mysql基础,或观看执行计划入门篇传送门: https:.html 终于总结到哦SQK执行计划的最 ...

  9. 1.mysql表优化和避免索引失效原则

    表优化 1.单表优化 建立索引 根据sql的实际解析顺序建立复合索引 最佳左前缀,保持索引的定义和使用顺序一致 2.多表优化 连接查询 小表驱动大表:对于双层循环来说,外层循环(数据量)越小,内层循环 ...

随机推荐

  1. REBEL IDEA热部署插件使用

    启动 一.在IDEA 的Plugins中搜索Jrebel for intellij 插件 二.https://my.jrebel.com/account/how-to-activate 注册或者使用f ...

  2. 安装ie时,报:此安装不支持您的操作系统的当前语言

    打开注册表(win的"运行"栏键入 regedit 再按 OK )的HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Nls/ ...

  3. 网络-udp

    1. 网络:把双方或者多方的设备(电脑,智能手机,ipad等)连接起来的一个工具     1.1 学习网络的目的: 通过网络把数据从一方传递到另外一方,完成数据的共享 2. ip地址     2.1: ...

  4. 树莓派+花生棒+leanote搭建自己的笔记服务器

    背景 对于一个程序猿来说.女朋友可以(暂时)没有,但是不能没有一个很好的记笔记的应用.因为记笔记可以帮助自己积累学习提升自己.每一次回头看自己记得笔记,你都会有新的理解. 也许有人会说,用有道云啊,有 ...

  5. 十九、Hadoop学记笔记————Hbase和MapReduce

    概要: hadoop和hbase导入环境变量: 要运行Hbase中自带的MapReduce程序,需要运行如下指令,可在官网中找到: 如果遇到如下问题,则说明Hadoop的MapReduce没有权限访问 ...

  6. Sequel自动生成Select语句

    Sequel 是 Mac 上的一款不错的 mysql 可视化编辑, 它有一个非常好的功能是可以定制自己的插件, 这就是Bundles. 利用这个功能可以写出自己常用的一些sql. 查询语句是最常用的, ...

  7. Android开发——子进程更新UI

    方式一:Handler和Message ① 实例化一个Handler并重写handlerMessage()方法 private Handler handler = newHandler() { pub ...

  8. 基于Jmeter+maven+Jenkins构建性能自动化测试平台

      一.目的: 为能够将相关系统性能测试做为常规化测试任务执行,且可自动无人值守定时执行并输出性能测试结果报告及统计数据,因此基于Jmeter+maven+Jenkins构建了一套性能自动化测试平台 ...

  9. 两个标签页定位第二个标签页元素时显示element not visible

    问题描述 web页面有两个标签页, 当转换到第二个标签页定位元素时, 显示element not visible. 代码 ... //省略 WebElement ele= browser.getEle ...

  10. Protostuff序列化分析

    前言最近项目中需要将业务对象直接序列化,然后存数据库:考虑到序列化.反序列化的时间以及生产文件的大小觉得Protobuf是一个很好的选择,但是Protobuf有的问题就是需要有一个.proto的描述文 ...