<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        oracle標量子查詢簡介和表連接改寫

        來源:懂視網 責編:小采 時間:2020-11-09 13:08:36
        文檔

        oracle標量子查詢簡介和表連接改寫

        oracle標量子查詢簡介和表連接改寫:之前小魚就聽過了標量子查詢,不過對于其中的細節理解還是遠遠不夠,借助一部分資料和自己測試對標量子查詢做一點簡單的分析和介紹。 Oracle允許在select子句中包含單行子查詢,這個也就是oracle的標量子查詢,標量子查詢有點類似于外連接,當使用到外連接時
        推薦度:
        導讀oracle標量子查詢簡介和表連接改寫:之前小魚就聽過了標量子查詢,不過對于其中的細節理解還是遠遠不夠,借助一部分資料和自己測試對標量子查詢做一點簡單的分析和介紹。 Oracle允許在select子句中包含單行子查詢,這個也就是oracle的標量子查詢,標量子查詢有點類似于外連接,當使用到外連接時

        之前小魚就聽過了標量子查詢,不過對于其中的細節理解還是遠遠不夠,借助一部分資料和自己測試對標量子查詢做一點簡單的分析和介紹。 Oracle允許在select子句中包含單行子查詢,這個也就是oracle的標量子查詢,標量子查詢有點類似于外連接,當使用到外連接時

        之前小魚就聽過了標量子查詢,不過對于其中的細節理解還是遠遠不夠,借助一部分資料和自己測試對標量子查詢做一點簡單的分析和介紹。

        Oracle允許在select子句中包含單行子查詢,這個也就是oracle的標量子查詢,標量子查詢有點類似于外連接,當使用到外連接時我們可以靈活的將其轉化為標量子查詢。

        SQL> create table t1 as select * from all_users;

        Table created.

        SQL> create table t2 as select * from all_objects;

        Table created.

        SQL> select a.object_id,(select b.username from t1 b where a.owner=b.username) f
        rom t2 a;

        49812 rows selected.

        Execution Plan
        ----------------------------------------------------------
        Plan hash value: 1364172329

        --------------------------------------------------------------------------
        | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
        --------------------------------------------------------------------------
        | 0 | SELECT STATEMENT | | 53276 | 1560K| 152 (1)| 00:00:02 |
        |* 1 | TABLE ACCESS FULL| T1 | 1 | 17 | 2 (0)| 00:00:01 |
        | 2 | TABLE ACCESS FULL| T2 | 53276 | 1560K| 152 (1)| 00:00:02 |
        --------------------------------------------------------------------------

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

        1 - filter("B"."USERNAME"=:B1)

        Note
        -----
        - dynamic sampling used for this statement

        Statistics
        ----------------------------------------------------------
        13 recursive calls
        0 db block gets
        4282 consistent gets
        0 physical reads
        0 redo size
        1176699 bytes sent via SQL*Net to client
        37012 bytes received via SQL*Net from client
        3322 SQL*Net roundtrips to/from client
        0 sorts (memory)
        0 sorts (disk)
        49812 rows processed

        標量子查詢其實還是一個子查詢,那么它究竟是如何查詢的:首先走的是外部的查詢,比如上一個sql語句執行計劃,先全表掃描的T2 a,然后取T2 a表的每一行數據就去和T1 b去過濾,過濾條件是a.owner=b.username,如果符合則返回子查詢的值,如果不符合則用null補充。當然這個時候還有個類似的filter去重的運算,對于t2 a中重復的數據行不用再去和t1 b去過濾。

        而上面這個標量子查詢的sql語句其實是等價于下面外連接sql語句的:
        SQL> select a.object_id,b.username from t2 a,t1 b
        2 where a.owner=b.username(+) ;

        49812 rows selected.

        Execution Plan
        ----------------------------------------------------------
        Plan hash value: 535089106

        ------------------------------------------------------------------------------
        | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
        ------------------------------------------------------------------------------
        | 0 | SELECT STATEMENT | | 53276 | 2445K| 155 (2)| 00:00:02 |
        |* 1 | HASH JOIN RIGHT OUTER| | 53276 | 2445K| 155 (2)| 00:00:02 |
        | 2 | TABLE ACCESS FULL | T1 | 23 | 391 | 2 (0)| 00:00:01 |
        | 3 | TABLE ACCESS FULL | T2 | 53276 | 1560K| 152 (1)| 00:00:02 |
        ------------------------------------------------------------------------------

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

        1 - access("A"."OWNER"="B"."USERNAME"(+))

        Note
        -----
        - dynamic sampling used for this statement

        Statistics
        ----------------------------------------------------------
        9 recursive calls
        0 db block gets
        4043 consistent gets
        0 physical reads
        0 redo size
        1176659 bytes sent via SQL*Net to client
        37012 bytes received via SQL*Net from client
        3322 SQL*Net roundtrips to/from client
        2 sorts (memory)
        0 sorts (disk)
        49812 rows processed

        而如果標量子查詢中如果主查詢的一行對應子查詢返回有多個值,這個是不允許的
        SQL> select a.username,b.object_id from t1 a,t2 b
        2 where a.username=b.owner(+);

        29742 rows selected.

        Execution Plan
        ----------------------------------------------------------
        Plan hash value: 1823443478

        ---------------------------------------------------------------------------
        | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
        ---------------------------------------------------------------------------
        | 0 | SELECT STATEMENT | | 53276 | 2445K| 155 (2)| 00:00:02 |
        |* 1 | HASH JOIN OUTER | | 53276 | 2445K| 155 (2)| 00:00:02 |
        | 2 | TABLE ACCESS FULL| T1 | 23 | 391 | 2 (0)| 00:00:01 |
        | 3 | TABLE ACCESS FULL| T2 | 53276 | 1560K| 152 (1)| 00:00:02 |
        ---------------------------------------------------------------------------

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

        1 - access("A"."USERNAME"="B"."OWNER"(+))

        Note
        -----
        - dynamic sampling used for this statement

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

        SQL> select a.username,(select b.object_id from t2 b where a.username=b.owner) f
        rom t1 a;
        select a.username,(select b.object_id from t2 b where a.username=b.owner) from t
        1 a
        *
        ERROR at line 1:
        ORA-01427: single-row subquery returns more than one row

        這里由于a.username=b.owner,其中b.owner有多個相同的值,所以這里返回的b.object_id可能有多個值,這里就出現上述的ora-01427錯誤。

        標量子查詢中也可以有聚合函數的出現:
        SQL> set autotrace traceonly;
        SQL> select a.username,max(b.object_id) from t1 a,t2 b
        2 where a.username=b.owner(+)
        3 group by a.username;

        23 rows selected.

        Execution Plan
        ----------------------------------------------------------
        Plan hash value: 577572187

        ----------------------------------------------------------------------------
        | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
        ----------------------------------------------------------------------------
        | 0 | SELECT STATEMENT | | 53276 | 2445K| 159 (4)| 00:00:02 |
        | 1 | HASH GROUP BY | | 53276 | 2445K| 159 (4)| 00:00:02 |
        |* 2 | HASH JOIN OUTER | | 53276 | 2445K| 155 (2)| 00:00:02 |
        | 3 | TABLE ACCESS FULL| T1 | 23 | 391 | 2 (0)| 00:00:01 |
        | 4 | TABLE ACCESS FULL| T2 | 53276 | 1560K| 152 (1)| 00:00:02 |
        ----------------------------------------------------------------------------

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

        2 - access("A"."USERNAME"="B"."OWNER"(+))

        Note
        -----
        - dynamic sampling used for this statement

        Statistics
        ----------------------------------------------------------
        92 recursive calls
        0 db block gets
        777 consistent gets
        685 physical reads
        0 redo size
        1169 bytes sent via SQL*Net to client
        503 bytes received via SQL*Net from client
        3 SQL*Net roundtrips to/from client
        2 sorts (memory)
        0 sorts (disk)
        23 rows processed

        SQL> select a.username,(select max(b.object_id) from t2 b where b.owner=a.userna
        me) from t1 a;

        23 rows selected.

        Execution Plan
        ----------------------------------------------------------
        Plan hash value: 367820

        ---------------------------------------------------------------------------
        | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
        ---------------------------------------------------------------------------
        | 0 | SELECT STATEMENT | | 23 | 391 | 2 (0)| 00:00:01 |
        | 1 | SORT AGGREGATE | | 1 | 30 | | |
        |* 2 | TABLE ACCESS FULL| T2 | 533 | 15990 | 152 (1)| 00:00:02 |
        | 3 | TABLE ACCESS FULL | T1 | 23 | 391 | 2 (0)| 00:00:01 |
        ---------------------------------------------------------------------------

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

        2 - filter("B"."OWNER"=:B1)

        Note
        -----
        - dynamic sampling used for this statement

        Statistics
        ----------------------------------------------------------
        9 recursive calls
        0 db block gets
        15929 consistent gets
        0 physical reads
        0 redo size
        1206 bytes sent via SQL*Net to client
        503 bytes received via SQL*Net from client
        3 SQL*Net roundtrips to/from client
        0 sorts (memory)
        0 sorts (disk)
        23 rows processed

        但是我們注意到上述標量子查詢卻存在一個問題,就是無法將子查詢展開為表連接,換句話說無法采用靈活的hash join outer的關聯方式。

        關于標量子查詢和表關聯的性能簡介:
        如果主查詢返回的數據較多,而子查詢中又沒有高效的索引,關聯列對應的主查詢表又沒有較多的重復值,那么這個標量子查詢的執行成本是很大的,如上面的標量子查詢和外連接的sql語句中可以看出外連接IO成本要明顯小于標量子查詢。

        但是標量子查詢oracle內部確是有優化的,優化器cache了中間的結果,如果結果集不大,子查詢中又有高效的索引,那么這個標量子查詢可能會比常規的表關聯更加高效。

        小魚列出幾種常會涉及到的標量子查詢和表連接的sql改寫:
        1 最簡單的標量子查詢
        table :a(a1,a2),b(a1,b2)
        select a2,(select b2 from b where b.a1=a.a1) from a

        表連接:
        select a2,b2 from a,b where a.a1=b.a1(+);

        2 子查詢中限制返回一行數據
        table :a(a1,a2),b(a1,b2)
        select a2,(select b2 from b where b.a1=a.a1 and rownum=1) from a

        表連接:
        SELECT a2, c.b2
        FROM a,
        (SELECT b2, ROW_NUMBER () OVER (PARTITION BY a1 ORDER BY a1) cn
        FROM b
        WHERE cn = 1) c
        WHERE a.a1 = c.b2(+);

        3 子查詢帶有聚合函數
        table :a(a1,a2),b(a1,b2)
        select a2,(select sum(b2) from b where b.a1 = a.a1) from a

        表連接1:
        SELECT a2, bb.sum_value
        FROM a,
        ( SELECT SUM (b2) sum_value, a1
        FROM b
        GROUP BY a1) bb
        WHERE a.a1 = b.a1(+);
        表連接2:
        SELECT a2, SUM (b2)
        FROM a, b
        WHERE a.a1 = b.a1(+)
        GROUP BY a2;

        4 查詢中包括好幾個標量子查詢
        table :a(a1,a2),b(a1,b2),c(a1,b2,c2)
        SELECT a.a2,
        (SELECT c2
        FROM b, c
        WHERE b.a1 = a.a1 AND b.b2 = c.b2 AND ROWNUM = 1),
        (SELECT b2
        FROM b
        WHERE b.a1 = a.a1 AND ROWNUM = 1),
        (SELECT c2
        FROM c
        WHERE c.a1 = a.a1 AND ROWNUM = 1)
        FROM a

        表連接:
        SELECT a.a2,
        bb.c2,
        cc.b2,
        dd.c2
        FROM (SELECT c2,
        b.a1,
        ROW_NUMBER () OVER (PARTITION BY b.a1 ORDER BY b.a1) cnt
        FROM b, c
        WHERE b.b2 = c.b2 AND cnt = 1) bb,
        (SELECT b2, ROW_NUMBER () OVER (PARTITION BY a1 ORDER BY a1) cnt
        FROM b
        WHERE cnt = 1) cc,
        (SELECT c2, ROW_NUMBER () OVER (PARTITION BY a1 ORDER BY a1) cnt
        FROM c
        WHERE cnt = 1) dd,
        a
        WHERE a.a1 = bb.a1(+) AND a.a1 = cc.a1(+) AND a.a1 = dd.a1(+);

        SELECT a2,
        (SELECT SUM (c2)
        FROM b, c
        WHERE b.a1 = a.a1 AND b.b2 = c.b2),
        (SELECT SUM (b2)
        FROM b
        WHERE b.a1 = a.a1),
        (SELECT SUM (c2)
        FROM c
        WHERE c.a1 = a.a1)
        FROM a
        表連接:
        SELECT a2,
        bb.sum1,
        cc.sum2,
        dd.sum3
        FROM ( SELECT SUM (c2) sum1, b.a1
        FROM b, c
        WHERE b.b2 = c.b2
        GROUP BY b.a1) bb,
        ( SELECT SUM (b2) sum2, a1
        FROM b
        GROUP BY a1) cc,
        ( SELECT SUM (c2) sum3, a1
        FROM c
        GROUP BY a1) dd,
        a
        WHERE a.a1 = bb.a1(+) AND a.a1 = cc.a1(+) AND a.a1 = dd.a1(+);

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        oracle標量子查詢簡介和表連接改寫

        oracle標量子查詢簡介和表連接改寫:之前小魚就聽過了標量子查詢,不過對于其中的細節理解還是遠遠不夠,借助一部分資料和自己測試對標量子查詢做一點簡單的分析和介紹。 Oracle允許在select子句中包含單行子查詢,這個也就是oracle的標量子查詢,標量子查詢有點類似于外連接,當使用到外連接時
        推薦度:
        標簽: 查詢 連接 量子
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 免费大片黄在线观看| 免免费国产AAAAA片| 最近在线2018视频免费观看| 成人午夜免费福利视频| 久久亚洲私人国产精品| 国产h视频在线观看网站免费| 亚洲美女精品视频| 999国内精品永久免费视频| 国产成人亚洲合集青青草原精品| 免费观看美女用震蛋喷水的视频| 亚洲国产成人精品久久| 成人最新午夜免费视频| 国产综合成人亚洲区| 亚洲人成人无码网www国产| 亚洲av乱码一区二区三区| 丁香花免费完整高清观看| 亚洲av永久无码精品秋霞电影影院| 亚洲午夜福利在线视频| 中国一级特黄的片子免费| 亚洲成AV人片天堂网无码| 九九综合VA免费看| 日本一线a视频免费观看| 边摸边脱吃奶边高潮视频免费 | 久久久久久AV无码免费网站| 日本视频免费在线| jizz免费一区二区三区| 亚洲AV乱码久久精品蜜桃| 久久精品免费网站网| 久久亚洲国产伦理| 97无码免费人妻超级碰碰夜夜| 18禁亚洲深夜福利人口| 无人在线直播免费观看| 偷自拍亚洲视频在线观看| 亚洲国产精品无码专区在线观看| 亚洲性线免费观看视频成熟| 亚洲国产成人AV网站| 综合自拍亚洲综合图不卡区| 在线看片无码永久免费aⅴ | 中国china体内裑精亚洲日本| 日本三级2019在线观看免费| 久久精品国产亚洲AV|