mysql 大于号 优化_SQL优化 MySQL版 - 避免索引失效原则(二)

避免索引失效原则(二)

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

避免索引失效原则(一)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;

22aed8d8b15d6ae206269a156653531d.png

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

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

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

我们查看执行结果:

9ae1481ed5e31977c97a13f617703471.png

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

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

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

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

d267830ad01e3c22014fce21129f23be.png

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

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

明显的概率问题

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

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

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

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

e3a2e232ebe1720e0eb475e08a1f005b.png

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

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

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

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

f322077f9d5255fe1518ce7714f08455.png

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

通过后两个例子我们发现,就改了一个数,索引都不一样了,所以,这就是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我是加了一个索引的,但是看一下看一下执行结果:

bc2fda6e5a948a81d2b13e3ccb945a8a.png

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

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

执行结果:

21803aeb52c3799795aa23b927a6b2d1.png

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

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

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这个字段的索引失效了;

今日感悟:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/347845.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js中数组增加添加元素的push方法

特别注意&#xff1a;push&#xff08;&#xff09;方法返回的是增加后新数组的长度&#xff0c;即元素个数。 var arryTest ["星期一","星期二"]; var add "星期三"&#xff1b; var length arryTest.push(add); //length3格式结构&#xf…

ajax处理返回的xml数据,使用AJAX调用WebService返回xml不返回json原因以及解决办法...

初次尝试用AJAX调用webservice&#xff0c;结果无论怎么设置webservice返回的都是xml对象&#xff0c;一般的jquery处理json是更方便的。webservice理论上将下面这段代码按照说明取消注释&#xff0c;就可以返回json数据了。// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服…

mysql 唯一索引 死锁_MySQL 死锁套路:唯一索引 S 锁与 X 锁的爱恨情仇

毫不夸张的说&#xff0c;有一半以上的死锁问题由唯一索引贡献&#xff0c;后面介绍的很多死锁的问题都跟唯一索引有关。这次我们讲一段唯一索引 S 锁与 X 锁的爱恨情仇我们来看一个简化过的例子# 构造数据CREATE TABLE t1 (id int(11) NOT NULL AUTO_INCREMENT,name varchar(1…

ejb 示例 2018_EJB钝化和激活示例

ejb 示例 2018在本教程中&#xff0c;我们将了解状态Java企业会话Bean中激活和钝化的工作方式。 1.简介 有状态会话Bean通常保存有关特定客户端的信息&#xff0c;并在整个会话中保存该信息。 但是&#xff0c;事实是&#xff0c;客户端会话往往会在相当长的时间内保持活动状态…

js微信小程序页面左上角返回跳转指定页面

微信小程序非导航栏tabBar页面左上角返回默认返回上一次的页面&#xff08;即进入当前页面的前一页面&#xff09;&#xff0c;如果需要自定义页面&#xff0c;可以通过js中onUnload函数进行指定页面跳转。 ①关闭所有页&#xff0c;打开url指定页面 onUnload: function () {…

服务器mysql显示链接次数太多,服务器mysql显示链接次数太多

服务器mysql显示链接次数太多 内容精选换一换在本章节中&#xff0c;您将会把游戏应用部署到CCE云容器引擎中&#xff0c;您需要执行以下操作&#xff1a;创建集群&#xff1a;集群是运行应用的逻辑分组&#xff0c;包含一组云服务器资源&#xff0c;每个节点对应一台云服务器。…

laravel5.6 mysql_快速入门 |《Laravel 5.6 中文文档 5.6》| Laravel China 社区

本文档最新版为 8.x&#xff0c;旧版本可能放弃维护&#xff0c;推荐阅读最新版&#xff01;数据库&#xff1a;入门简介Laravel 能使用原生 SQL、查询构造器 和 Eloquent ORM 在各种数据库后台与数据库进行非常简单的交互。当前 Laravel 支持四种数据库:MySQLPostgresSQLiteSQ…

计算机二级web题目(5)--js(Javascript)基础

1 [单选题] 在以下选项中,不合法的标识符是(A)。 A. a*b B. small C. score D. average grade 解析&#xff1a;点击查看标识符命名规则 2 [单选题]在HTML页面中哪些部分能够插入JavaScript?&#xff08;C&#xff09; A. <body>部分 B. <head>部分 C. <body&g…

使用JUnit 5在Mockito中方便地进行模拟–官方方式

从版本2.17.0开始&#xff0c;如果使用JUnit 5&#xff0c; Mockito提供了官方&#xff08;内置&#xff09;支持来管理模拟生命周期。 入门 为了利用该集成&#xff0c;需要在JUnit 5的junit-platform-engine旁边添加Mockito的mockito-junit-jupiter依赖项&#xff08;有关详…

esp32搭建文件服务器,ESP32入门示例 - SD卡Web服务器

这个是来自ESP32官方示例的改版&#xff0c;官方的示例由于存在一些问题所以我进行了修改原本的示例有点逻辑上的问题&#xff0c;所以进行了一些修改主要修改有&#xff1a;1.新增SD卡测试部分 复制自官方SD卡示例2.新增一个根目录页&#xff0c;访问根目录就可以看到3.修改了…

mysql 配置文件在哪_MySQL+MyCat分库分表 读写分离配置

一、 MySQLMyCat分库分表1 MyCat简介java编写的数据库中间件Mycat运行环境需要JDK。Mycat是中间件&#xff0c;运行在代码应用和MySQL数据库之间的应用。前身&#xff1a; corba&#xff0c;是阿里开发的数据库中间件&#xff0c;实现MySQL数据库分库分表集群管理的中间件&…

字符串String截取字符char

字符串类的charAt() 方法可返回指定位置的字符。 stringObject.charAt(index)从键盘输入获取了一个字符串&#xff0c;将其数据类型转换为字符型。 Scanner scan new Scanner(System.in); String str scan.next(); char ca str.charAt(0);示例&#xff1a; import java.u…

gradle构建工具_Gradle:我们需要另一个构建工具吗?

gradle构建工具在Java开发的早期&#xff0c;我们要么没有太多的构建工具需求&#xff0c;要么就使用了其他环境中的工具。 我仍然记得构建shell脚本并创建用于开发Java的文件。 生成文件特别有趣&#xff0c;因为这是一个在设计时就没有考虑到Java的工具。 迁移到不同的操作系…

db platform mysql_数据库移植: 从Oracle移植到MySQL 注意databasePlatform | 学步园

采用Spring框架、JPA操作数据库开发一个小网站过程中&#xff0c;遇到需要将数据库从Oracle移植到MySQL&#xff0c;在进行单元测试时遇到如下错误&#xff1a;Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown table SEQ_GEN_IDENTIT…

Java基本语法(14)--for循环结构

循环结构&#xff1a;在某些条件满足的情况下&#xff0c;反复执行特定代码的功能。 基本格式&#xff1a; for (①初始化部分; ②循环条件部分; ④迭代部分)&#xff5b; ③循环体部分; &#xff5d;如果①&#xff0c;④部分多条语句&#xff0c;语句之间用“&#xff0c;”…

Java 8中的功能接口是什么? @功能注释和示例

函数接口是Java 8最重要的概念之一&#xff0c;实际上为lambda表达式提供了动力&#xff0c;但是许多开发人员没有首先了解函数接口在Java 8中的作用就花了很多精力来理解它&#xff0c;并花时间学习lambda表达式和Stream API。除非您知道什么是功能接口以及lambda与它之间的关…

win10存储池_3个光威480G SSD组WIN10存储池,深度测试到底值不值得搞

上次由于我SSD不够&#xff0c;所以我用虚拟硬盘的方式&#xff0c;虚拟了3个VHDX硬盘&#xff0c;组了个奇偶校验的存储池&#xff0c;并且简单的做了测试。测试结果是&#xff0c;组存储池确实提高了我们的数据安全性。WIN10存储池&#xff0c;可以让我们玩家省去组RAID&…

求最大公约数最小公倍数

最大公约数小于两个数小的那个&#xff0c;最小公倍数大于两个数大的那个。 求最大公约数从大到小寻找&#xff0c;求最小公倍数从小到大寻找&#xff0c;也就是说循环方向。 import java.util.Scanner;public class JavaTest {public static void main(String[] args) {//从键…

biginteger和long精度_修复Long类型太长,而Java序列化JSON丢失精度问题的方法

造成原因&#xff1a;JS内置有32位整数&#xff0c;而number类型的安全整数是53位。如果超过53位&#xff0c;则精度会丢失。正如现在后台传来一个64位的Long型整数&#xff0c;因此超过了53位&#xff0c;所以后台返回的值和前台获取的值会不一样。Java序列化JSON时long型数值…

Java基本语法(15)--while循环结构do-while循环结构

基本格式 ①初始化部分 while(②循环条件部分)&#xff5b;③循环体部分;④迭代部分; }①初始化部分; do{③循环体部分;④迭代部分; }while(②循环条件部分);注意不要忘记声明④迭代部分。否则&#xff0c;循环将不能结束&#xff0c;变成死循环。 while循环先判断后循环体&a…