Note2 : MySql 逻辑查询处理

Note2 MySql 逻辑查询处理
      查询操作是关系数据库最为频繁的操作之一,其显得尤为重要。
      SQL 语言不同于其他编程语言,明显的区别在于代码的顺序上面,SQL语言中第一个被处理的语言总是FROM子句。
     下面来具体分析每个查询处理的阶段:

      1、FROM :
      对FROM子句的左表a和右表b进行执行笛卡尔积,产生虚拟表VT1
      笛卡尔积也称为交叉连接, 连接后数据条数为a*b

      2、ON :
      对虚拟表VT1进行筛选, 满足条件的行才会插入到虚拟表VT2中去。
      一般的编程语言逻辑表达式的值只有TRUE和FALSE两种,在关系数据库中还有三值逻辑表达式。
还有一种UNKNOWN的情况,比如select null = null 返回的是null ,而不是1, select  1= null返回的还是null,结果是未知的。
那么如果2个值都为NULL,用ON过滤,是不是满足合并的条件呢?
是不满足的,对于ON过滤条件下得NULL值比较,比较结果是UNKNOWN,被看做FALSE来处理,即2个NULL不相同,
总结:在产生VT2的时候,会增加一个额外的列表示ON的过滤条件返回值(TRUE、FALSE、UNKOWNN),取出TRUE的记录,产生VT2
      PS:有下面2种情况下,2个NULL的值比较是相同的:

      GROUP BY 和ORDER BY 。
 

      3、JOIN
     默认情况下,多表的连接是内连接,如果指定了外连接(如左连接Left Join 、右连接 Right Join) ,那么会保留未匹配的行作为外部行到VT2中,产生了虚拟表VT3

     4、WHERE
    对于虚拟表VT3进行WHERE过滤,只有符合条件的记录才会插入到虚拟表VT4中。
    2种过滤是不容许的:
        4.1 数据还没有分组
      select cust_no ,count(cust_no) from order.order where count(cust_no)<2
        4.2 没有列选取
      select order_no as orderNo ,cust_no as custNo from order.order where  custNo = 1133
         因为还没有走到select那一步呢。
         那么WHERE过滤和ON过滤有什么差别呢?
         如果是内连接,那他们是没有差别的,因为没有添加外部行操作,但是如果是外连接,on在过滤完后会再次添加保留被过滤掉的记录,而where 是永久性的过滤。
 

     5、GROUP BY
       根据GROUP BY 子句中列,对VT4中得记录进行分组操作,产生VT5
      PS:group by一般会和聚合函数一起使用,如SUM \COUNT\ GROUP_CONCAT.
      GROUP_CONCAT一般默认连接的是1024个字节,如果超过,会自动截取,可以改变系统默认值。

     6、CUBE| ROLLUP
    对VT5进行CUBE ROLLUP操作,产生VT6

     7、HAVING
     对VT6进行having过滤,having过滤是对分组条件的过滤,符合条件的插入到VT7中
     having count(o.order_no) <2

    8、SELECT
      选择指定的列,插入到VT8中
   列的别名不能在select中其他别名表达式中使用,如:
   select order_no as o, o+1 as n from order.orders
 

   9、DISTINCT
     去掉重复的数据,产生VT9

   10、ORDER BY
      对于VT9 进行排序操作,产生VT10
     关系数据库的表中的数据可以看成是一个集合,其实是无序的。有时候,我们不用Order By也可以得到一个结果是有序的,其实不是这样的。
    不要为表中的行假定任何特定的顺序,如果需要有序排列,必须使用order by 来排序。
   show status like'%sort%' 
  1. mysql> show global status like 'sort%';  
  2. +-------------------+----------+  
  3. | Variable_name     | Value    |  
  4. +-------------------+----------+  
  5. | Sort_merge_passes | 2136     |  
  6. | Sort_range        | 81888    |  
  7. | Sort_rows         | 35918141 |  
  8. | Sort_scan         | 55269    |  
 
    进行了55269次扫描,扫描了
35918141  行数据,可以通过增加索引来减小排序的开销。
  null 在Order by 中被看成最小值,如果升序排列,会第一个选出

11、limit 
   取出指定行的记录,返回用户,产生VT11 ,在实际运用中使用其分页比较多,有时候查问题时候,直接limit 1会提高速度。

   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值