码迷,mamicode.com
首页 > 数据库 > 详细

MySql 技术内幕 (查询处理和子查询)

时间:2020-06-02 09:29:24      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:增加   定义   color   width   笛卡尔积   from   size   alias   临时   

一. 查询流程

  1.查询流程中, 每个操作都产生一个虚拟表, 除了最后一个,其他对用户都是透明的.

  2.查询流程

  技术图片

     3. DISTINCT

   如果在查询中指定了DISTINCT子句,则会创建一张内存临时表(内存中放不下就放磁盘),表结构和虚表一样,不同的是distinct列,增加了一个唯一索引,以此来去重数据;

  4.物理查询处理

   ①parser(分析器)分析sql语句,optimizer(优化器))对SQL进行优化,选择一条最优路径选取数据.

   ②添加索引避免笛卡尔积的产生,大幅缩短语句运行的时间;

  

二. 子查询概述

子查询 : select中嵌套另一个select;

 ANY,IN,SOME,ALL用法,  in是some的别名; not in是 "<>all" 的别名;

 

三. 独立子查询

标量子查询, 多值子查询;

独立子查询:子查询对外部查询无依赖;

相关子查询: 子查询对外部查询有依赖;

mysql对IN优化存在一个问题,如果不是显示的列定义,如果in(‘a‘,‘b‘,‘c‘), 则会转换成exists的相关子查询;  

大多数情况下,mysql都会讲独立子查询转换为相关子查询;

逻辑IO次数可能比物理IO次数大,可以通过慢查询日志,优化逻辑IO;

MariaDb提供了相对独立子查询的优化;如开启SEMI JOIN的优化后,不再将IN转化为exists语句, 而是先将独立子查询产生的结果生成一张物化视图,之后在对外部查询的表进行join操作;

 

四. 相关子查询(dependent Subquery

子查询会对外部查询的每一行进行一次计算,但是优化器内部有很多优化方式处理;

对相关子查询的处理, 减少子查询与外部查询的匹配次数;

使用派生表优化子查询,例如,使用子查询作为派生表B,再将表A和表B进行联接;

技术图片

 

五. exists谓词

 exists 和in 

exists只会返回true或false,

in会返回true,false和unknown(当做false处理);

in 和exists大部分情况具有相同的执行计划,

 
not in和not exists 

not in和not exists具有非常不同的执行计划;

not in( NULL),返回的总是false和unknown,

比如 null in (‘a‘,‘b‘,NULL) 返回null;

‘c‘ not in (‘a‘,‘b‘,NULL),返回NULL;

使用not in可以先过滤掉null值;

 

六. 派生表

从虚表中产生的,形式: FROM (subquery expression) as  derived_table_alias;

没有物化,速度可能非常慢,尤其是大数据量的表;

 

七.  MaruaDB对SEEMI JOIN的优化 (半连接)

一般形式:

select ...from out_table
where expr In ( select ...from inner_table ...) and ...
目前mysql和oracle将semi join转换成了exists语句;
 
Table pullout优化
根据唯一索引将子查询重写为join语句,
 
Duplicate Weedout优化
外部查询条件列是唯一的,优化器会先将子查询查出的结果进行去重.
 
Materilization优化
优化器将独立子查询结果填充到一张物化临时表;
根据join顺序,
分为Materilization scan: join时将物化临时表和表联结;
分为Materilization lookup: join时将表和物化临时联结;

 

MySql 技术内幕 (查询处理和子查询)

标签:增加   定义   color   width   笛卡尔积   from   size   alias   临时   

原文地址:https://www.cnblogs.com/coloz/p/13029116.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!