当前位置:首页 > 数据库 > 正文

mysql查询语句性能 MySQL查询优化

mysql查询语句性能 MySQL查询优化

今天给各位分享mysql查询语句性能的知识,其中也会对MySQL查询优化进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!mysql:一条SQL查询...

今天给各位分享mysql查询语句性能的知识,其中也会对MySQL查询优化进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

mysql:一条SQL查询语句是如何执行的

本篇文章会分析下一个sql语句在MySQL中的执行流程,包括sql的查询在MySQL内部会怎么流转,sql语句的更新是怎么完成的。

在分析之前我会先带着你看看MySQL的基础架构,知道了MySQL由那些组件组成已经这些组件的作用是什么,可以帮助我们理解和解决这些问题。

一MySQL基础架构分析

1.1MySQL基本架构概览

下图是MySQL的一个简要架构图,从下图你可以很清晰的看到用户的SQL语句在MySQL内部是如何执行的。

先简单介绍一下下图涉及的一些组件的基本作用帮助大家理解这幅图,在1.2节中会详细介绍到这些组件的作用。

连接器:身份认证和权限相关(登录MySQL的时候)。查询缓存:执行查询语句的时候,会先查询缓存(MySQL8.0版本后移除,因为这个功能不太实用)。分析器:没有命中缓存的话,SQL语句就会经过分析器,分析器说白了就是要先看你的SQL语句要干嘛,再检查你的SQL语句语法是否正确。优化器:按照MySQL认为最优的方案去执行。执行器:执行语句,然后从存储引擎返回数据。

简单来说MySQL主要分为Server层和存储引擎层:

Server层:主要包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图,函数等,还有一个通用的日志模块binglog日志模块。存储引擎:主要负责数据的存储和读取,采用可以替换的插件式架构,支持InnoDB、MyISAM、Memory等多个存储引擎,其中InnoDB引擎有自有的日志模块redolog模块。现在最常用的存储引擎是InnoDB,它从MySQL5.5.5版本开始就被当做默认存储引擎了。

1.2Server层基本组件介绍

1)连接器

连接器主要和身份认证和权限相关的功能相关,就好比一个级别很高的门卫一样。

主要负责用户登录数据库,进行用户的身份认证,包括校验账户密码,权限等操作,如果用户账户密码已通过,连接器会到权限表中查询该用户的所有权限,之后在这个连接里的权限逻辑判断都是会依赖此时读取到的权限数据,也就是说,后续只要这个连接不断开,即时管理员修改了该用户的权限,该用户也是不受影响的。

2)查询缓存(MySQL8.0版本后移除)

查询缓存主要用来缓存我们所执行的SELECT语句以及该语句的结果集。

连接建立后,执行查询语句的时候,会先查询缓存,MySQL会先校验这个sql是否执行过,以Key-Value的形式缓存在内存中,Key是查询预计,Value是结果集。如果缓存key被命中,就会直接返回给客户端,如果没有命中,就会执行后续的操作,完成后也会把结果缓存起来,方便下一次调用。当然在真正执行缓存查询的时候还是会校验用户的权限,是否有该表的查询条件。

MySQL查询不建议使用缓存,因为查询缓存失效在实际业务场景中可能会非常频繁,假如你对一个表更新的话,这个表上的所有的查询缓存都会被清空。对于不经常更新的数据来说,使用缓存还是可以的。

所以,一般在大多数情况下我们都是不推荐去使用查询缓存的。

MySQL8.0版本后删除了缓存的功能,官方也是认为该功能在实际的应用场景比较少,所以干脆直接删掉了。

3)分析器

MySQL没有命中缓存,那么就会进入分析器,分析器主要是用来分析SQL语句是来干嘛的,分析器也会分为几步:

第一步,词法分析,一条SQL语句有多个字符串组成,首先要提取关键字,比如select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。

第二步,语法分析,主要就是判断你输入的sql是否正确,是否符合MySQL的语法。

完成这2步之后,MySQL就准备开始执行了,但是如何执行,怎么执行是最好的结果呢?这个时候就需要优化器上场了。

4)优化器

优化器的作用就是它认为的最优的执行方案去执行(有时候可能也不是最优,这篇文章涉及对这部分知识的深入讲解),比如多个索引的时候该如何选择索引,多表查询的时候如何选择关联顺序等。

可以说,经过了优化器之后可以说这个语句具体该如何执行就已经定下来。

5)执行器

当选择了执行方案后,MySQL就准备开始执行了,首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果。

二语句分析

2.1查询语句

说了以上这么多,那么究竟一条sql语句是如何执行的呢?其实我们的sql可以分为两种,一种是查询,一种是更新(增加,更新,删除)。我们先分析下查询语句,语句如下:

select*fromtb_studentAwhereA.age='18'andA.name='张三';

结合上面的说明,我们分析下这个语句的执行流程:

先检查该语句是否有权限,如果没有权限,直接返回错误信息,如果有权限,在MySQL8.0版本以前,会先查询缓存,以这条sql语句为key在内存中查询是否有结果,如果有直接缓存,如果没有,执行下一步。通过分析器进行词法分析,提取sql语句的关键元素,比如提取上面这个语句是查询select,提取需要查询的表名为tb_student,需要查询所有的列,查询条件是这个表的id='1'。然后判断这个sql语句是否有语法错误,比如关键词是否正确等等,如果检查没问题就执行下一步。接下来就是优化器进行确定执行方案,上面的sql语句,可以有两种执行方案:a.先查询学生表中姓名为“张三”的学生,然后判断是否年龄是18。b.先找出学生中年龄18岁的学生,然后再查询姓名为“张三”的学生。那么优化器根据自己的优化算法进行选择执行效率最好的一个方案(优化器认为,有时候不一定最好)。那么确认了执行计划后就准备开始执行了。进行权限校验,如果没有权限就会返回错误信息,如果有权限就会调用数据库引擎接口,返回引擎的执行结果。

2.2更新语句

以上就是一条查询sql的执行流程,那么接下来我们看看一条更新语句如何执行的呢?sql语句如下:

updatetb_studentAsetA.age='19'whereA.name='张三';

我们来给张三修改下年龄,在实际数据库肯定不会设置年龄这个字段的,不然要被技术负责人打的。其实条语句也基本上会沿着上一个查询的流程走,只不过执行更新的时候肯定要记录日志啦,这就会引入日志模块了,MySQL自带的日志模块式binlog(归档日志),所有的存储引擎都可以使用,我们常用的InnoDB引擎还自带了一个日志模块redolog(重做日志),我们就以InnoDB模式下来探讨这个语句的执行流程。流程如下:

先查询到张三这一条数据,如果有缓存,也是会用到缓存。然后拿到查询的语句,把age改为19,然后调用引擎API接口,写入这一行数据,InnoDB引擎把数据保存在内存中,同时记录redolog,此时redolog进入prepare状态,然后告诉执行器,执行完成了,随时可以提交。执行器收到通知后记录binlog,然后调用引擎接口,提交redolog为提交状态。更新完成。

这里肯定有同学会问,为什么要用两个日志模块,用一个日志模块不行吗?

这是因为最开始MySQL并没与InnoDB引擎(InnoDB引擎是其他公司以插件形式插入MySQL的),MySQL自带的引擎是MyISAM,但是我们知道redolog是InnoDB引擎特有的,其他存储引擎都没有,这就导致会没有crash-safe的能力(crash-safe的能力即使数据库发生异常重启,之前提交的记录都不会丢失),binlog日志只能用来归档。

并不是说只用一个日志模块不可以,只是InnoDB引擎就是通过redolog来支持事务的。那么,又会有同学问,我用两个日志模块,但是不要这么复杂行不行,为什么redolog要引入prepare预提交状态?这里我们用反证法来说明下为什么要这么做?

先写redolog直接提交,然后写binlog,假设写完redolog后,机器挂了,binlog日志没有被写入,那么机器重启后,这台机器会通过redolog恢复数据,但是这个时候bingog并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。先写binlog,然后写redolog,假设写完了binlog,机器异常重启了,由于没有redolog,本机是无法恢复这一条记录的,但是binlog又有记录,那么和上面同样的道理,就会产生数据不一致的情况。

如果采用redolog两阶段提交的方式就不一样了,写完binglog后,然后再提交redolog就会防止出现上述的问题,从而保证了数据的一致性。那么问题来了,有没有一个极端的情况呢?假设redolog处于预提交状态,binglog也已经写完了,这个时候发生了异常重启会怎么样呢?这个就要依赖于MySQL的处理机制了,MySQL的处理过程如下:

判断redolog是否完整,如果判断是完整的,就立即提交。如果redolog只是预提交但不是commit状态,这个时候就会去判断binlog是否完整,如果完整就提交redolog,不完整就回滚事务。

这样就解决了数据一致性的问题。

三总结MySQL主要分为Server曾和引擎层,Server层主要包括连接器、查询缓存、分析器、优化器、执行器,同时还有一个日志模块(binlog),这个日志模块所有执行引擎都可以共用,redolog只有InnoDB有。引擎层是插件式的,目前主要包括,MyISAM,InnoDB,Memory等。查询语句的执行流程如下:权限校验(如果命中缓存)---》查询缓存---》分析器---》优化器---》权限校验---》执行器---》引擎更新语句执行流程如下:分析器----》权限校验----》执行器---》引擎---redolog(prepare状态---》binlog---》redolog(commit状态)

mysql查询表里的重复数据方法

可以通过groupby和having语句来查询重复数据。1.使用groupby和having语句可以查询表中的重复数据。2.groupby语句用来将结果集中相同的列分组,而having语句则是对每个组进行条件过滤。因此,我们可以通过将所有列作为分组字段来确定所有重复值,然后使用having语句设置重复值计数器进行过滤。3.此外,我们也可以使用distinct关键字在select语句中去除重复数据。但是,如果需要统计重复数据的数量,则需要使用groupby和having语句。

sql查询语句详解

SQL查询语句是用于从数据库中检索数据的命令。它们允许你指定要检索的表和字段,并定义筛选条件和排序规则。下面是SQL查询语句的基本结构和一些常见的关键词:

SELECT:用于指定要检索的字段(列),可以使用通配符*表示所有字段。

FROM:用于指定要检索的表。

WHERE:用于指定筛选条件,只返回满足条件的行。

ORDERBY:用于指定按照哪个字段排序返回的结果。

GROUPBY:用于将结果按照某个字段进行分组。

HAVING:用于指定筛选分组后的结果。

以下是一个简单的SQL查询语句示例:

```sql

SELECT*FROMemployeesWHEREage>25ORDERBYnameASC;

```

这个查询语句将从名为employees的表中选择所有的字段,并且只返回年龄大于25的行。结果将按照姓名升序排序。

除了基本的SELECT语句,SQL还提供了许多其他功能,如使用聚合函数(SUM、AVG等)、连接多个表、使用子查询等。这些功能可以帮助你更复杂地查询和分析数据。具体的语法和用法可能会因SQL的方言(如MySQL、Oracle、SQLServer等)而有所不同。

为了更深入地了解SQL查询语句的详细用法和常见操作,请参考相应的SQL文档、教程或参考书籍。这些资源可以帮助你学习更高级的查询技巧和优化方法。

如何查看mysql执行过的语句

1.mysql查看已经执行的历史sql语句方法:开启日志模式:

SETGLOBALlog_output=‘TABLE’;SETGLOBALgeneral_log=‘ON’;

2.找到文件位置:/home/root/mysql/data/mysql/general_log.CSV,查看mysql执行过的语句。

3.关闭日志模式:

SETGLOBALlog_output=‘FILE’;SETGLOBALgeneral_log=‘OFF’;在查询到所需要的记录之后,应尽快关闭日志模式,占用磁盘空间比较大

mysql查询语句和oracle查询语句的差别大吗l

首先是大体一致的,只是分页查询时oracle用的伪列(rownum),mysql用的是limit,具体的可以百度一下分页;

另外oracle对sql语句要求更为严格,而且oracle里变量较mysql更多点,oracle中有number型,有大数据类型,mysql没得;

另外举个例子,oracle不能插入为空列,而mysql是可以的(个人觉得,不知道正确与否)。还有他们两者函数有不同之处,如转日期函数oracle是to_date('要转的字符串','格式')--selectto_date('2004-05-0713:23:44','yyyy-mm-ddhh24:mi:ss')fromdual,而mysql是str_to_date('08/09/2008','%m/%d/%Y');--2008-08-09//都是针对字符串转日期来的。

还有一点,我们常常希望主键可以自动增长,避免我们插入数据时的重复问题,但是oracle不能设置列自动增长,而mysql是可以的,oracle可以用序列加触发器来解决自动增长问题达到与mysql一样的效果。

总体来说百分之九十的sql语句是没区别的。总体来说oracle的格式严格点,对有些字符型的还必须加单引号才能插入,mysql要求就没这么多了。还有当向数据库插入一个日期时,mysql可以直接插入成功,但是oracle需要先转化为sql里面的日期类型才行;oracle较mysql而言更安全,但是收费的,一般大公司用的多。oracle还有存储过程和函数,触发器这些这是mysql没有的。大体就是这样吧。

好了,文章到此结束,希望可以帮助到大家。

最新文章