axure9 条件中条件_SQL中join条件和where条件的执行次序

测试目的

  1. 测试关联查询的执行过程,过滤条件写在where后和on后的区别

  2. 认识“谓词下推”

测试设计

    客户表CUST

    f6dd42b5e5cacc321879feac34cd1ef1.png

    订单表 ORDERS

    9212b4d171cf27d50a336d80f35bf552.png

现在想查询年龄小于18岁的客户的订单情况。有以下两个sql语句

SELECT * FROM CUST A LEFT JOIN ORDERS B ON A.CUSTID=B.CUSTID WHERE AGE <18SELECT * FROM CUST A LEFT JOIN ORDERS B ON A.CUSTID=B.CUSTID AND AGE <18

测试过程

首先,关联的中间结果如下

SELECT * FROM CUST A LEFT JOIN ORDERS B ON A.CUSTID=B.CUSTID

c5d9fd5eaa8d3351a4eb5f9099fb1d38.png

第一个sql执行结果如下,是先连接两个表,再用age<18对中间结果进行过滤。

2e5e077bc644c83f0f88fc0e48343e20.png

第二个sql执行结果,不满足age<18的行不会连接,但左表所有记录都会显示。

50b642367422512826f808a7cc837b0c.png

谓词在on后面的关联成本更高,除非业务需要,否则把谓词放在where后面更好。

测试结果

        以上测试得出结论,多表关联是先连接再执行where后的过滤条件(谓词)。那么问题来了,把全表的数据从存储层读取至内存,在计算引擎(内存)中关联后在过滤,在表数据量很大的时候性能消耗必定很大。能不能在关联之前,从底层取数据的时候就用where条件把不需要的数据过滤掉呢?这个思想就是谓词下推。

谓词下推

        谓词下推的目的就是通过将一些过滤条件尽可能的在最底层执行可以减少上层交互的数据量,从而提升性能。往高大上的方面说,就是将过滤表达式下推到存储层直接过滤数据,减少传输到计算层的数据量。

        以下面的sql为例

SELECT * FROM CUST A LEFT JOIN ORDERS B ON A.CUSTID=B.CUSTID WHERE AGE <18

        按照sql标准的执行过程,需要先对CUST表和ORDERS表做全表扫描,数据读取至内存中再进行关联和过滤。DB2强大的优化器,会在真正执行sql前对其进行重写,把过滤条件age<10改成子查询移到关联前执行(谓词下推至DMS数据管理层或IDM索引管理层),可以大大降低Join操作的输入数据,提升SQL的执行效率。改写后的sql如下

SELECT Q4.$C5 AS "CUSTID", Q4.NAME AS "NAME", Q4.AGE AS "AGE", Q4.ORDERID AS "ORDERID", Q4.$C2 AS "CUSTID", Q4.AMOUNT AS "AMOUNT"FROM  (SELECT    Q3.AMOUNT,   Q3.ORDERID,  Q3.CUSTID,    Q2.NAME,  Q2.AGE,  Q2.CUSTID   FROM    (SELECT  Q1.CUSTID,  Q1.NAME,  Q1.AGE     FROM   DB2INST1.CUST AS Q1     WHERE  (Q1.AGE < 18) ) AS Q2     LEFT OUTER JOIN DB2INST1.ORDERS AS Q3    ON (Q2.CUSTID = Q3.CUSTID)  )AS Q4

       通过理解sql关联查询的执行次序和谓词下推思想,在以后的解决sql性能问题时会有更加深入的思路。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值