兩個左串連SQL執行計畫解析(Oracle和PGSQL對比):

來源:互聯網
上載者:User

標籤:from   null   round   連結   lse   ase   臨時   通過   www.   

上一篇解析連結如下:
https://www.cnblogs.com/wcwen1990/p/9325968.html

1、SQL樣本1:

SQL> select *
from (
select * from tmp1 where c >= 1
) t1 left join (
select * from tmp2 where b < 30
) t2 on t1.a = t2.a
and t2.d > 1 and t1.e >= 2
where t1.b < 50
;

     A        B           C      E         A        B       D          E
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
      2       20           2      2         2           20       2          2
      4       40           4      4
      3       30           3      3
      1       10           1      1


Execution Plan
----------------------------------------------------------
Plan hash value: 2592321047

---------------------------------------------------------------------------
| Id  | Operation       | Name | Rows  | Bytes | Cost (%CPU)| Time      |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    4 |   416 |    7  (15)| 00:00:01 |
|*  1 |  HASH JOIN OUTER   |      |    4 |   416 |    7  (15)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL| TMP1 |    4 |   208 |    3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| TMP2 |    1 |    52 |    3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("TMP1"."A"="TMP2"."A"(+))
        filter("TMP1"."E">=CASE    WHEN ("TMP2"."A"(+) IS NOT NULL) THEN 2
           ELSE 2 END )
    2 - filter("TMP1"."B"<50 AND "C">=1)
    3 - filter("TMP2"."D"(+)>1 AND "B"(+)<30)

Note
-----
    - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
       0  recursive calls
       0  db block gets
       7  consistent gets
       0  physical reads
       0  redo size
        1082  bytes sent via SQL*Net to client
     524  bytes received via SQL*Net from client
       2  SQL*Net roundtrips to/from client
       0  sorts (memory)
       0  sorts (disk)
       4  rows processed
      

postgres=# explain analyze select *
postgres-# from (
postgres(# select * from tmp1 where c >= 1
postgres(# ) t1 left join (
postgres(# select * from tmp2 where b < 30
postgres(# ) t2 on t1.a = t2.a
postgres-# and t2.d > 1 and t1.e >= 2
postgres-# where t1.b < 50
postgres-# ;
                                                   QUERY PLAN                                                 
--------------------------------------------------------------------------------------------------------------
  Hash Left Join  (cost=34.90..80.00 rows=181 width=32) (actual time=0.021..0.035 rows=4 loops=1)
    Hash Cond: ("outer".a = "inner".a)
    Join Filter: ("outer".e >= 2)
    ->  Seq Scan on tmp1  (cost=0.00..34.45 rows=181 width=16) (actual time=0.006..0.011 rows=4 loops=1)
          Filter: ((c >= 1) AND (b < 50))
    ->  Hash  (cost=34.45..34.45 rows=181 width=16) (actual time=0.007..0.007 rows=1 loops=1)
          ->  Seq Scan on tmp2  (cost=0.00..34.45 rows=181 width=16) (actual time=0.002..0.003 rows=1 loops=1)
                Filter: ((b < 30) AND (d > 1))
  Total runtime: 0.063 ms
(9 rows)


SQL執行計畫的分析:

1) 全表掃描左表TMP1,同時根據TMP1表子查詢條件"C">=1和where過濾條件"T1"."B"<50聯合過濾,即filter("TMP1"."B"<50 AND "C">=1),計算結果暫存資料表記為tmp1;
2) 全表掃描右表TMP2,同時根據TMP2表子查詢條件"B"(+)<30和on子句"T2"."D"(+)>1聯合過濾,即filter("TMP2"."D"(+)>1 AND "B"(+)<30),計算結果暫存資料表記為tmp2;
3) 左表TMP1及右表TMP2處理後暫存資料表tmp1和tmp2通過access("TMP1"."A"="TMP2"."A"(+))串連條件進行Hash Left Join操作,左暫存資料表結果集全量返回,右表不匹配行置為null,返回結果暫存資料表記為tmp3;
4) 返回結果集。


2、SQL樣本2:

SQL> select *
from (
select * from tmp1 where c >= 1
) t1 left join (
select * from tmp2 where b < 30
) t2 on t1.a = t2.a
and t2.d > 1 and t1.e >= 2
where t1.b < 50 and t2.e <= 3
;

     A        B           C      E         A        B       D          E
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
      2       20           2      2         2           20       2          2


Execution Plan
----------------------------------------------------------
Plan hash value: 1630095649

---------------------------------------------------------------------------
| Id  | Operation       | Name | Rows  | Bytes | Cost (%CPU)| Time      |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    1 |   104 |    7  (15)| 00:00:01 |
|*  1 |  HASH JOIN       |      |    1 |   104 |    7  (15)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL| TMP2 |    1 |    52 |    3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| TMP1 |    3 |   156 |    3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("TMP1"."A"="TMP2"."A")
    2 - filter("TMP2"."E"<=3 AND "TMP2"."D">1 AND "B"<30)
    3 - filter("TMP1"."B"<50 AND "TMP1"."E">=2 AND "C">=1)

Note
-----
    - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
       9  recursive calls
       0  db block gets
      15  consistent gets
       0  physical reads
       0  redo size
     981  bytes sent via SQL*Net to client
     524  bytes received via SQL*Net from client
       2  SQL*Net roundtrips to/from client
       0  sorts (memory)
       0  sorts (disk)
       1  rows processed

SQL>


postgres=# select *
postgres-# from (
postgres(# select * from tmp1 where c >= 1
postgres(# ) t1 left join (
postgres(# select * from tmp2 where b < 30
postgres(# ) t2 on t1.a = t2.a
postgres-# and t2.d > 1 and t1.e >= 2
postgres-# where t1.b < 50 and t2.e <= 3
postgres-# ;
  a | b  | c | e | a | b  | d | e
---+----+---+---+---+----+---+---
  2 | 20 | 2 | 2 | 2 | 20 | 2 | 2
(1 row)

postgres=# explain analyze select *
postgres-# from (
postgres(# select * from tmp1 where c >= 1
postgres(# ) t1 left join (
postgres(# select * from tmp2 where b < 30
postgres(# ) t2 on t1.a = t2.a
postgres-# and t2.d > 1 and t1.e >= 2
postgres-# where t1.b < 50 and t2.e <= 3
postgres-# ;
                                                  QUERY PLAN                                                 
-------------------------------------------------------------------------------------------------------------
  Hash Join  (cost=38.68..78.43 rows=18 width=32) (actual time=0.033..0.041 rows=1 loops=1)
    Hash Cond: ("outer".a = "inner".a)
    ->  Seq Scan on tmp1  (cost=0.00..38.53 rows=60 width=16) (actual time=0.007..0.011 rows=3 loops=1)
          Filter: ((c >= 1) AND (e >= 2) AND (b < 50))
    ->  Hash  (cost=38.53..38.53 rows=60 width=16) (actual time=0.008..0.008 rows=1 loops=1)
          ->  Seq Scan on tmp2  (cost=0.00..38.53 rows=60 width=16) (actual time=0.003..0.005 rows=1 loops=1)
                Filter: ((b < 30) AND (d > 1) AND (e <= 3))
  Total runtime: 0.070 ms
(8 rows)

postgres=#


SQL執行計畫的分析:

1) 全表掃描左表TMP2,同時根據TMP2表子查詢條件"B"<30和where過濾條件"TMP2"."E"<=3及ON子句過濾條件"TMP2"."D">1聯合過濾,即filter("TMP2"."E"<=3 AND "TMP2"."D">1 AND "B"<30),計算結果暫存資料表記為tmp1;
2) 全表掃描右表TMP1,同時根據TMP1表子查詢條件"C">=1和where子句過濾條件"TMP1"."B"<50及ON子句"TMP1"."E">=2聯合過濾,即filter("TMP1"."B"<50 AND "TMP1"."E">=2 AND "C">=1),計算結果暫存資料表記為tmp2;
3) 暫存資料表tmp1和tmp2通過access("TMP1"."A"="TMP2"."A")串連條件進行Hash Join串連操作(此處left join寫法已經被轉換為內連結),返回匹配結果暫存資料表記為tmp3;
4) 返回結果集。

兩個左串連SQL執行計畫解析(Oracle和PGSQL對比):

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.