首页 > 数据库 >如何判断一个sql走不走索引?

如何判断一个sql走不走索引?

时间:2023-12-21 20:13:26浏览次数:37  
标签:判断 t1 索引 sql test where select

在你的工作中,可能写过很多个sql,我相信最让你头疼的,一定还是那风骚的查询sql。

我猜你很可能有这样的体验,好不容易写了一个牛逼哄哄的查询sql,兴奋的上线投产。

结果,在第二天阳光明媚的日子里,dba把你的sql揪了出来,揪出来还不算,dba还要发到群里@你,说:“嗨,兄弟,瞅瞅你写的个啥?”

接着,dba把你苦思冥想的sql贴在群里,这时,是不是感觉自己的内裤被扒出来展览一样?

对的,慢sql,是业务研发做sql优化逃避不了的一个问题。

要避免慢sql,最重要的,就是索引。

聪明的你应该看出来了,我要讲一讲,如何判断一个sql走不走索引?

以mysql为例,你可能马上就要骂我:“这还不简单,explain一下不就完事?”

是的,你很聪明,不过explain出来的结果,你得明白为什么,这样才能知道如何解决以及优化。

接着,来一起浪一把!

先创建如下表:

create table t1(id int primary key, a int, b int,c varchar(16),d varchar(16), index index_a(a), index index_cd(c,d));

然后,我写了五个sql,你瞅瞅看走不走索引。

select * from t1 where a>5;

select * from t1 where c='test';

select * from t1 where c like 'test%';

select * from t1 where d like 'test%';

select * from t1 where c like '%test';

可能你已经知道答案了,如下:

select * from t1 where a>5;  //走索引

select * from t1 where c='test';  //走索引

select * from t1 where c like 'test%';  //走索引

select * from t1 where d like 'test%'; //不走索引

select * from t1 where c like '%test';  //不走索引

那原理是什么呢?

mysql的表数据,本质上就是一个写在磁盘的B+树,专业名词叫做聚簇索引。而其他的索引,也是以B+树的形式写在文件中。

B+树的数据,不是顺序的,但却是有序的。

这就意味着,比如select * from t1 where a>5; 这个sql的a>5,从数据结构上,是可以推出来数据的大致位置的,既然如此,那便无需全表扫描,可以用到索引a。mysql,也正是这么做的。

理解了范围查询能走索引,接下来看第2个sql

select * from t1 where c='test';

由于c、d两个字段有组合索引,将第2个sql做一下改造

等价于

select * from t1 where c='test' and c||d>='test';

这下明白了不?有了范围查询,那就能走索引了。

再来看第3个sql,同理:

等价于

select * from t1 where c like 'test%' and c||d>='test';  

所以,还是能够走索引。

再来看第4、5个sql,咱费劲脑子,也做不了如上的等价sql转换,事实上,这两个sql确实也走不了索引。

说到这,我想你大概想到了一个专业名词:最左匹配原则。

对,就是这个原则,而这个原则的算法依据,便是我所阐述的。

希望看了这篇文章,能对你有些帮助,不再被dba轻易抓住。

标签:判断,t1,索引,sql,test,where,select
From: https://www.cnblogs.com/kingcode/p/17919939.html

相关文章

  • 同样的SQL,怎么突然就慢了?
    本篇文章素材来源于某银行系统的一次性能问题分析。许久没写这种troubleshooting类型的技术文章了,因为曾在服务公司呆过多年,工作原因,这方面之前做的多,听的更多,导致已经达到在自己认知维度下的一个小瓶颈,纯技术型的问题,稍微常见的基本都遇到过,非常少见的也基本是bug类(软件缺陷只能......
  • 在 MySQL 中,你可以使用 `AVG()` 函数来计算一组值或表达式的平均值。`AVG()` 函数的基
    在MySQL中,AVG()函数在计算平均值时会自动忽略NULL值¹⁴。也就是说,它只会计算所有非空值的平均值³。例如,假设你有一个包含以下值的列:90,80,70,85,95,NULL,NULL。在这种情况下,AVG()函数将只计算非空值的平均值,即:而不是将NULL值视为0并计算所有值的平均值。如果你需......
  • PostgreSQL从入门到精通教程 - 第39讲:数据库完全恢复
       PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUGPG技术大讲堂。 第39讲:数据库完全恢复 PostgreSQL第39讲:12月23日(......
  • centos7上源码安装postgresql 13.6
    1环境描述操作系统:Centos7.6postgresql:13.6安装方式:源码安装2创建用户#groupadd-g2000pgsql#useradd-u2000-gpgsqlpgsql3目录规划#mkdir-p/postgresql/{pgdata,archive,scripts,backup,pg13,soft,pg_log}#chown-Rpgsql:pgsql/postgresql#......
  • postgresql常用创建用户和授权
    需求(1)给用户a创建一个数据库,并且给a用户对这个库有所有权限(2)给read_a用户对这个数据库有只读权限步骤1.创建用户a2.创建数据库db_a,并设置owner为a3.回收默认的publicschemacreate权限4.设置db_a的publicschema默认的owner为a5.创建只读用户read_a6.用a用户给read_a......
  • golang简单判断22-65535开发情况
    packagemainimport( "fmt" "net" "sync" "time")funcmain(){ server:="42.51.129.175"//要检查的服务器地址 ports:=make([]int,65535)//要检查的端口范围,从22到65535 fori:=22;i<=65535;i++{ ports......
  • mysql
    MYSQL1.安装2.用法sql语句可单行或多行,以分号结尾;MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。单行注释:--注释内容或#注释内容(MySQL特有)多行注释:/*注释*/3.mysql数据类型​ 数值:tinyint:1个字节(小整数类型)int:4个字节(大整数类型)double......
  • docker初步入门学习安装redis和mysql
    dockerrun--namemyredis-p6379:6379-dredisredis-server--appendonlyyesdockerrun--namemysql-eMYSQL_ROOT_PASSWORD=123456-d-p3306:3306mysql:5.7.27dockerpullmysql:5.7.27dockerrun-d--hostnamemy-rabbit--namemyra......
  • sql server pre-login troubleshooting
    wireshark抓包之后,首先过滤数据库服务器的IPip.src==172.22.58.4orip.dst==172.22.58.4找到第一条TCP握手记录之后,右键选中,FollowTCPstream然后会自动标记筛选出,从握手到断开的所有packet数据包tcp.streameq56 UsingSQLServer’sSNITracetoTroubleshootNetwor......
  • MySQL 8 半同步复制
    安装半同步复制半同步复制是通过插件的形式实现的。必须要在源库和副本上安装插件。源库和副本有不同的插件。插件安装后,可通过与之相关的系统变量对其进行控制。只有安装了相关插件,这些系统变量才可用。要使用半同步复制,必须满足以下要求:·要求MySQL服务器支持动态加载。要......