sql优化2

  • 一条查询sql语句的执行流程:
  1. FROM <表名>
    选取表,将<left_table>及<right_table>表数据通过笛卡尔积生成虚表VT1(此时VT1包括表中所有的字段?),
  2. ON <筛选条件>
    对笛卡尔积的虚表VT1根据条件进行筛选VT2
  3. JOIN <join, left join, right join...> <join表>
    指定join,保留表中未匹配的行就会作为外部行添加到虚拟表VT2中,产生虚表VT3。例如left join会将左表的剩余数据添加到虚表VT2中,生成虚表VT3
  4. WHERE <where条件>
    对上述虚表VT3进行筛选, 将符合<where-condition>的记录才会被插入到虚表VT4
    此时还没有进行group by,因此WHERE中出现对统计的过滤是不对的(不可以使用聚合函数),若需要则在having中实现。
    请思考一下,对于同样的筛选条件:在on和where 处进行筛选有结果会有不同?
  5. GROUP BY <分组条件>
    分组, 根据分组条件,对VT4进行分组操作,生成虚表VT5(若是有group by,那么后面的所有步骤都只能得到的VT4的列及聚合函数(count、sum、avg等),即VT5虚表只会生成这些)
    注意:所有select的字段,除聚合函数中的字段外,都必须在group by中出现
  6. HAVING <分组筛选>
    对分组后的结果进行筛选,即对虚表VT5进行筛选生成VT6
  7. SELECT<返回数据列表>
    选择指定的列,生成虚拟表VT7(再次提醒:若有group by子句中,则此处除了group by子句中的列+聚合函数除外,不能再出现其它的列。请思考下,为什么不建议Select *from?)
  8. DISTINCT
    数据除重,生成VT8
  9. ORDER BY<排序条件>
    将虚表VT8按照<order_by_list>进行排序操作,产生虚拟表VT9,请注意:这是唯一的一个可以使用select列表中别名的步骤
  10. LIMIT <行数限制>
    取出指定行的记录,产生虚拟表VT10, 并将结果返回
  • 扩展:带有子查询的执行顺序(坚持小表驱动大表的原则)
    1. 不相关子查询:子查询的查询条件不依赖于父查询(由里向外 逐层处理。即每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件)
    select * from emp where sal = (select max(sal) from emp);
    先执行内层查询,作为where 条件再执行外层查询
    2. 相关子查询:子查询的查询条件依赖于父查询(先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若WHERE子句返回值为真,则取此元组放入结果表,
    然后再取外层表的下一个元组,重复这一过程,直至外层表全部检查完为止)
    select * from dept d where exists(select * from emp e where e.deptno = d.deptno);
    先执行外层查询,再执行内层查询
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容