美文网首页MySQL
你清楚 SQL 的执行顺序吗?

你清楚 SQL 的执行顺序吗?

作者: ixdba | 来源:发表于2022-07-27 11:46 被阅读0次

    目标读者

    • 开发人员
    • 学生
    • DBA
    • 其他工作中涉及数据库的相关人员

    一. 概述

    1.1. 测试环境概览

    • 操作系统:CentOS 7.9 x86_64
    • 数据库:MySQL 5.7.38
    • Docker 版本:1.13.1-209

    为了快速部署测试环境,数据库运行于 Docker 内。

    1.2. 测试环境初始化

    启动 Docker 服务

    yum install -y docker
    
    systemctl start docker
    # 禁止开机自启动
    systemctl disable docker
    

    启动 MySQL 服务(Docker 内)

    mypwd='tiger'      # mysql 密码
    myport=33016       # mysql 端口
    myversion='5.7.38' # mysql 版本号
    
    docker run -itd \
      --name test-mysql \
      -e MYSQL_ROOT_PASSWORD="${mypwd}" \
      -p ${myport}:3306 \
      -d mysql:${myversion}
    
    docker ps | grep -w mysql
    # 2c5c103d94e4        mysql:5.7.38        "docker-entrypoint..."   35 seconds ago      Up 34 seconds       33060/tcp, 0.0.0.0:33016->3306/tcp   test-mysql
    

    验证 MySQL 服务启动成功

    yum install -y mysql
    
    [root@c7009 ~]# mysql -uroot -ptiger -h 127.0.0.1 --port 33016
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.7.38 MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MySQL [(none)]> select 'hello mysql';
    +-------------+
    | hello mysql |
    +-------------+
    | hello mysql |
    +-------------+
    1 row in set (0.00 sec)
    

    至此,MySQL 测试环境初始化完成。

    1.3. 为什么要了解 SQL 的执行顺序?

    有如下 SQL:

    select @rn := @rn + 1 as row_num,
           ht.name
    from mysql.help_topic ht,
         (select @rn := 0) as rn
    order by row_num;
    
    image.png

    如果你不能理解以上输出背后的逻辑,请继续往下看吧。

    二. SQL 执行顺序

    2.1. 优先级

    我们都知道,算术表达式中加减乘除是有优先级的,而一条 SQL 的各部分也是有执行先后顺序的:

    (8)select                  (9)distinct <select_list>
    (1)from <left_table>       (3)<join_type> join <right_table>
    (2)on <join_condition>
    (4)where <where_condition>
    (5)group by <group_by_list>
    (6)with {CUBE|ROLLUP}
    (7)having <having_condtion>
    (10)order by <order_by_list>
    (11)limit <limit_number>
    

    2.2. 验证

    回看 1.3 节 SQL,拆分后形成以下几部分:

    -- part 1
    select @rn := @rn + 1 as row_num,
           ht.name
    
    -- part 2
    from mysql.help_topic ht,
         (select @rn := 0) as rn
    
    -- part 3
    order by row_num;
    

    套用 2.1 节优先级列表,此 SQL 各部分执行顺序如下:

    • Step 1: part 2 - 写法相当于 ht cross join rn,先对 @rn 会话变量进行了赋值操作。
    • Step 2: part 1 - 每行对 @rn 进行递增操作(所谓行间计算)。
    • Step 3: part 3 - 对结果集进行排序。

    总结

    日常工作中,我们可能会遇到一些复杂 SQL,如果对 SQL 自身的执行顺序不了解,很难真正熟悉 SQL 所对应的业务逻辑。

    授人与渔

    如果你还想提升自身的 SQL 水平,以下书籍是比较推荐

    • SQL Cookbook
    • Oracle SQL 高级编程
    • SQL Server 2005 技术内幕 T-SQL 查询

    关于我

    经历:DBA 一枚,09 年开始接触数据库,一直专注于此领域。

    此系列文章初衷:多年学习/工作经验,有些沉淀,也想分享些东西出来,算对这个行业的一点点微薄贡献,希望 IT 这个圈子能越来越好。

    其他说明:不能保证全文没有任何不妥之处,如有发现,不吝赐教。

    相关文章

      网友评论

        本文标题:你清楚 SQL 的执行顺序吗?

        本文链接:https://www.haomeiwen.com/subject/iwyoirtx.html