暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【MySQL那些事】一条sql的寻宝之旅

搬运工大雄 2021-05-11
701
前言


很久很久以前,有一枚名叫坤仔的程序猿,他深知MySQL中的数据库是一个巨大的宝藏库,但是必须获得通行证sql,才能取得宝藏。话说sql又分为以下四类


SQL的分类


    DCL:数据控制语言,grant、deny、revoke、commit等
    DDL:数据定义语言,create table、view、index等
    DML:数据操作语言,select、update、insert、delete
    DQL:数据查询语言,select

    坤仔偶然间得到一条DQL查询语句

      select * from treasure

      他看到了发财的曙光,并开始了奇幻的寻宝之旅。


      开启旅程


      客户端将sql语句按照mysql的通信协议发送到服务端,服务端收到sql后为其创建一个线程去执行。

      坤仔好奇心很严重,想要看看数据库中有哪些线程在运行,以及他们的状态是什么,于是他查阅了葵花宝典,找到了查看命令

        show [full]  processlist;

        执行结果如下

        坤仔自然不认识这些字段代表什么意思,于是他继续翻阅葵花宝典,最终得到如下解释:

          User:当前连接的用户
          Host:发出该连接请求的ip及端口
          db:连接的数据库
          Command:连接的命令,对应的有休眠(sleep),查询(query),连接(connect)
          Time:连接持续的时间,单位是秒
          State:当前连接状态
          Info:显示当前sql


          查询缓存


          坤仔踏上寻宝之路后,遇到的第一关就是查询缓存,但是对它而言,这是好事情。

          在MySQL8.0以前,数据库提供了查询缓存模块,它是一个键值对结构,以整个sql、数据库名、客户端协议等作为key,查询的结果作为value。如果坤仔以前就拿着同样的sql取过宝藏,那么在这里就可以再次取得宝藏,而不用继续颠簸劳累的去寻宝。

          查询缓存的相关命令如下:

            //查看是否开启缓存
            SHOW VARIABLES LIKE 'have_query_cache';


            //缓存性能监控
            SHOW STATUS LIKE 'Qcache%'


            //清除所有缓存
            RESET QUERY CACHE;

            注意事项:

            1、数据库的版本、协议、字符集和查询的sql必须一样,否则不会命中key

            2、预处理语句等不确定性的sql不会被缓存

            3、如果表结构或者表的数据改变,那么缓存会被清理,即执行了insert、update、delete、alter table等语句

            一般来说,表的操作是很频繁的,所以查询缓存是非常不稳定的,而操作缓存也需要耗费一定的性能,故MySQL8.0以后直接将查询缓存模块删掉了

            坤仔是第一次来寻宝,所以他不可能轻而易举的在这里拿到宝藏,只得继续赶路。


            解析器


            坤仔来到第二关——解析器


            1、词法分析

            解析器会将sql中的每个单词按顺序提取出来,并判断是否为mysql关键字

            2、语法分析

            解析器会对词法分析的结果按照mysql的语法进行分析,最后生成一棵语法树

            如果sql语法不正确,例如缺少from关键字,就会提示如下错误


            3、预处理器

            生成语法树后,就会送到预处理器中,预处理器会校验表名、列名等结构信息,如果不存在则报错

            4、权限校验

            预处理器校验成功后,还会判断该用户有没有操作表的权限,如果没有,还是会报错

            幸好坤仔持有的sql语法是正确的,所以他顺利的通过了检查,并继续前进


            优化器


            坤仔到了第三关——优化器

            语法树最终会送入优化器,优化器会判断如何执行该sql效率会更高,最终确定一个执行方案。

            MySQL使用基于成本的优化器,它尝试预测一个查询使用某种执行计划时的成本,并选择成本最低的一个作为执行计划

            坤仔想看看查询成本,于是翻阅葵花宝典,找到一条命令可以获取最后一个查询sql的查询成本

            show status like 'last_query_cost';
            文章转载自搬运工大雄,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

            评论