• With As多表查询


    目录

    语法

    举例

    表关系

     分析

    mysql进程状态

             使用左连接


    语法

    1. with
    2. alias_name_01 as (查询SQL select * from table_name_01)
    3. alias_name_02 as (查询SQL select * from alias_name_01 an01,table_name_02 tn02 where an01.foreign_id = tn02.id)
    4. select * from alias_name_02 ;

    举例

    表关系

    1. CREATE TABLE ims.`ims_app_dept_info` (
    2. `app_dept_id` int NOT NULL AUTO_INCREMENT,
    3. `p_app_dept_id` int DEFAULT NULL,
    4. `dept_name` varchar(50) DEFAULT NULL COMMENT '部门名称',
    5. PRIMARY KEY (`app_dept_id`)
    6. ) COMMENT='组织机构表';
    7. CREATE TABLE ims.`ims_app_employee_info` (
    8. `app_emp_id` int NOT NULL AUTO_INCREMENT,
    9. `emp_name` varchar(50) DEFAULT NULL COMMENT '员工姓名',
    10. `emp_code` varchar(50) DEFAULT NULL COMMENT '员工编码',
    11. `app_dept_id` int DEFAULT NULL,
    12. PRIMARY KEY (`app_emp_id`)
    13. ) COMMENT='员工信息表';

            如上所示,有一个员工表,一个组织表,员工表关联到组织表,通过app_dept_id关联。

    1. with
    2. emp_info as (
    3. select * from ims.ims_app_employee_info t limit 100
    4. ),
    5. emp_all_info as (
    6. select
    7. ei.emp_name,ei.emp_code,dept.dept_name
    8. from emp_info ei,
    9. ims.ims_app_dept_info dept
    10. where
    11. dept.app_dept_id = ei.app_dept_id
    12. )
    13. select * from emp_all_info limit 3;

            使用上面的SQL,就可以查询两个表之间的数据,而不需要使用left join 关联。

     

     分析

     用explain可以看到这个SQL执行的大概过程。

    首先是从表t,也就是ims_app_employee_info中过滤出100条数据,这个过程是很快的。

    然后就是从ims_app_dept_info表,根据主键关联,速度也是很快的。

    最后是table=derived3这个表,这是一个假表,应该是临时表,没有用到任何key,所以应该是从100条数据中过滤出来3条。

    再看这张执行进程状态过程图,这里面查询时间总共是0.333s,

            从上图大概能猜到,创建了临时表用于存放这些查询数据,后面就是执行with这个SQL语句。

             这里有三个query end状态,并不是说执行了三次,也不是说移除了两张临时表。

            此处应该是进程执行是有时间的,query end表示查询结束,可以开始处理数据。

            而查询的数据是放在临时表中,数据处理完毕后会处于 removing tmp table。

            其实可以做个测试,比如explain select * from ims.ims_app_dept_info t,有时候也是会有三个query end状态。

            

    mysql进程状态

    query end这种状态发生后处理查询。
    removing tmp table线程移除临时表。 如果没有创建临时表,这种状态是不使用。
    closing tables线程改变表中的数据刷新到磁盘和关闭使用的表。
    end这发生在最后的清理工作,有ALTER TABLE , CREATE VIEW , DELETE , INSERT , SELECT或UPDATE语句。
    freeing items线程已执行的命令。 释放一些在这种状态下完成的项目,涉及的查询缓存。 这种状态通常后跟cleaning up 。
    init在发生之前的初始化ALTER TABLE , DELETE , INSERT , SELECT或UPDATE语句。 服务器在这种状态下采取的行动包括冲洗二进制日志中InnoDB日志,和一些查询缓存清理操作
    optimizing

    服务器执行查询的初始优化         

    preparing这种状态出现在查询优化过程中。

      使用左连接

    1. explain with
    2. emp_info as (
    3. select * from ims.ims_app_employee_info t limit 3
    4. ),
    5. emp_all_info as (
    6. select ei.emp_name,ei.emp_code,dept.dept_name
    7. from emp_info ei
    8. left join ims.ims_app_dept_info dept
    9. on dept.app_dept_id = ei.app_dept_id
    10. )
    11. select * from emp_all_info;
    12. explain
    13. select e.emp_name,e.emp_code,t.dept_name
    14. from ims.ims_app_employee_info e
    15. left join ims.ims_app_dept_info t
    16. on t.app_dept_id = e.app_dept_id
    17. limit 3;
    图一
    图一

     

    图二

             上述两个查询结果是一样的,执行时间也是基本相似,都是0.183s,也就是说基本对性能相差无几。

            但是从上述id的内容来看,猜测图一应该是执行了两次查询处理,图二可能只有一次。

  • 相关阅读:
    程序员喜欢Linux系统的原因有哪些?
    【博客480】prometheus-----数据查找过程
    Mysql索引 like篇
    固定元素宽度根据文本的长度缩小字号,超出缩小字号
    一年前端|17K|极光推送5轮面经
    RHCE之路配置本地DNS服务器的正反向解析
    【Educoder离散数学实训】集合及其基本运算的实现
    ARM64 linux并发与同步之内存屏障
    解析PR曲线与目标检测中的mAP指标
    6月25日PMI认证考点防疫要求及考场安排
  • 原文地址:https://blog.csdn.net/lw18751836671/article/details/126829369