• 彻底搞懂oracle的标量子查询


    oracle标量子查询和自己定义函数有时用起来比較方便,并且开发者也常常使用。数据量小还无所谓。数据量大,往往存在性能问题。

    下面測试帮助大家彻底搞懂标量子查询。 SQL> create table a (id int,name varchar2(10)); Table created. SQL> create table b (id int,name varchar2(10)); Table created. SQL> insert into a values (1,'a1'); 1 row created. SQL> insert into a values (2,'a2'); 1 row created. SQL> insert into b values (1,'b1'); 1 row created. SQL> insert into b values (2,'b2'); 1 row created. SQL> commit; Commit complete. SQL> @getlvall Session altered. SQL> select a.*,(select name from b where b.id=a.id) from a; ID NAME (SELECTNAMEFROMBWHER ---------- -------------------- -------------------- 1 a1 b1 2 a2 b2 SQL> @getplanspe PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SQL_ID 8rv825dykpx1m, child number 0 ------------------------------------- select a.*,(select name from b where b.id=a.id) from a Plan hash value: 2657529235 ------------------------------------------------------------------------------------ | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------ |* 1 | TABLE ACCESS FULL| B | 2 | 1 | 2 |00:00:00.01 | 14 | | 2 | TABLE ACCESS FULL| A | 1 | 2 | 2 |00:00:00.01 | 8 | ------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("B"."ID"=:B1) Note ----- - dynamic sampling used for this statement 22 rows selected.

    <strong>--由上面的运行计划能够知道,b表运行2次。返回2行</strong>
    SQL> insert into a values (3,'a3');
    1 row created.
    SQL> commit;
    Commit complete.
    SQL> select a.*,(select name from b where b.id=a.id) from a;
            ID NAME                 (SELECTNAMEFROMBWHER
    ---------- -------------------- --------------------
             1 a1                   b1
             2 a2                   b2
             3 a3
    SQL> @getplanspe
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID  8rv825dykpx1m, child number 0
    -------------------------------------
    select a.*,(select name from b where b.id=a.id) from a
    Plan hash value: 2657529235
    ------------------------------------------------------------------------------------
    | Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ------------------------------------------------------------------------------------
    |*  1 |  TABLE ACCESS FULL| B    |      3 |      1 |      2 |00:00:00.01 |      21 |
    |   2 |  TABLE ACCESS FULL| A    |      1 |      2 |      3 |00:00:00.01 |       8 |
    ------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("B"."ID"=:B1)
    Note
    -----
       - dynamic sampling used for this statement
    22 rows selected.
    <strong>--由上面的运行计划能够知道,b表运行3次。返回2行</strong>
    SQL> insert into a values (4,'a4');
    1 row created.
    SQL> insert into a values (5,'a5');
    1 row created.
    SQL> insert into a values (6,'a6');
    1 row created.
    SQL> insert into a values (7,'a7');
    1 row created.
    SQL> insert into a values (8,'a8');
    1 row created.
    SQL> insert into a values (9,'a9');
    1 row created.
    SQL> commit;
    Commit complete.
    SQL> select a.*,(select name from b where b.id=a.id) from a;
            ID NAME                 (SELECTNAMEFROMBWHER
    ---------- -------------------- --------------------
             1 a1                   b1
             2 a2                   b2
             3 a3
             4 a4
             5 a5
             6 a6
             7 a7
             8 a8
             9 a9
    9 rows selected.
    SQL> @getplanspe
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID  8rv825dykpx1m, child number 0
    -------------------------------------
    select a.*,(select name from b where b.id=a.id) from a
    Plan hash value: 2657529235
    ------------------------------------------------------------------------------------
    | Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ------------------------------------------------------------------------------------
    |*  1 |  TABLE ACCESS FULL| B    |      9 |      1 |      2 |00:00:00.01 |      63 |
    |   2 |  TABLE ACCESS FULL| A    |      1 |      2 |      9 |00:00:00.01 |       8 |
    ------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("B"."ID"=:B1)
    Note
    -----
       - dynamic sampling used for this statement
    22 rows selected.
    <strong>
    --由上面的运行计划能够知道,b表运行9次,返回2行</strong>
    SQL> update b set name='b1';
    2 rows updated.
    SQL> commit;
    Commit complete.
    SQL> select a.*,(select name from b where b.id=a.id) from a;
            ID NAME                 (SELECTNAMEFROMBWHER
    ---------- -------------------- --------------------
             1 a1                   b1
             2 a2                   b1
             3 a3
             4 a4
             5 a5
             6 a6
             7 a7
             8 a8
             9 a9
    9 rows selected.
    SQL> @getplanspe
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID  8rv825dykpx1m, child number 0
    -------------------------------------
    select a.*,(select name from b where b.id=a.id) from a
    Plan hash value: 2657529235
    ------------------------------------------------------------------------------------
    | Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ------------------------------------------------------------------------------------
    |*  1 |  TABLE ACCESS FULL| B    |      9 |      1 |      2 |00:00:00.01 |      63 |
    |   2 |  TABLE ACCESS FULL| A    |      1 |      2 |      9 |00:00:00.01 |       8 |
    ------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("B"."ID"=:B1)
    Note
    -----
       - dynamic sampling used for this statement
    22 rows selected.
    <strong>--由上面的运行计划能够知道,b表运行2次,返回2行</strong>
    SQL> insert into b values (3,'b1');
    1 row created.
    SQL> insert into b values (4,'b1');
    1 row created.
    SQL> insert into b values (5,'b1');
    1 row created.
    insert into b values (6,'b1');b1');
    1 row created.
    SQL> insert into b values (7,'b1');
    1 row created.
    SQL> insert into b values (8,'b1');
    1 row created.
    SQL> insert into b values (9,'b1');
    1 row created.
    SQL> commit;
    Commit complete.
    SQL> select a.*,(select name from b where b.id=a.id) from a;
            ID NAME                 (SELECTNAMEFROMBWHER
    ---------- -------------------- --------------------
             1 a1                   b1
             2 a2                   b1
             3 a3                   b1
             4 a4                   b1
             5 a5                   b1
             6 a6                   b1
             7 a7                   b1
             8 a8                   b1
             9 a9                   b1
    9 rows selected.
    SQL> @getplanspe
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID  8rv825dykpx1m, child number 0
    -------------------------------------
    select a.*,(select name from b where b.id=a.id) from a
    Plan hash value: 2657529235
    ------------------------------------------------------------------------------------
    | Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ------------------------------------------------------------------------------------
    |*  1 |  TABLE ACCESS FULL| B    |      9 |      1 |      9 |00:00:00.01 |      63 |
    |   2 |  TABLE ACCESS FULL| A    |      1 |      2 |      9 |00:00:00.01 |       8 |
    ------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("B"."ID"=:B1)
    Note
    -----
       - dynamic sampling used for this statement
    22 rows selected.
    <strong>--b.name字段所有为‘b1’。由上面的运行计划能够知道。b表运行9次。返回9行</strong>
    SQL> update a set id=1;
    9 rows updated.
    SQL> commit;
    Commit complete.
    SQL> select * from a;
            ID NAME
    ---------- --------------------
             1 a1
             1 a2
             1 a3
             1 a4
             1 a5
             1 a6
             1 a7
             1 a8
             1 a9
    9 rows selected.
    SQL> select * from b;
            ID NAME
    ---------- --------------------
             1 b1
             2 b1
             3 b1
             4 b1
             5 b1
             6 b1
             7 b1
             8 b1
             9 b1
    9 rows selected.
    SQL> select a.*,(select name from b where b.id=a.id) from a;
            ID NAME                 (SELECTNAMEFROMBWHER
    ---------- -------------------- --------------------
             1 a1                   b1
             1 a2                   b1
             1 a3                   b1
             1 a4                   b1
             1 a5                   b1
             1 a6                   b1
             1 a7                   b1
             1 a8                   b1
             1 a9                   b1
    9 rows selected.
    SQL> @getplanspe
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID  8rv825dykpx1m, child number 0
    -------------------------------------
    select a.*,(select name from b where b.id=a.id) from a
    Plan hash value: 2657529235
    ------------------------------------------------------------------------------------
    | Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    ------------------------------------------------------------------------------------
    |*  1 |  TABLE ACCESS FULL| B    |      1 |      1 |      1 |00:00:00.01 |       7 |
    |   2 |  TABLE ACCESS FULL| A    |      1 |      2 |      9 |00:00:00.01 |       8 |
    ------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("B"."ID"=:B1)
    Note
    -----
       - dynamic sampling used for this statement
    22 rows selected.
    SQL> 
    </pre><pre name="code" class="sql"><strong><span style="font-size:18px;">关联字段a.id所有为1。a表有9行,标量子查询相当于运行9次select name from b where b.id=1 ,oracle也不傻,starts=1。说明仅仅运行了1次。
    总结:
    理想状态下,a.id为主键,没有反复值。那么a表返回多少行,b表就要被运行多少次。
    特殊情况下,a.id的distinct值仅仅有n个,那么b表仅仅运行n次。

    </span></strong>



  • 相关阅读:
    装饰器
    返回函数
    用Token令牌维护微服务之间的通信安全的实现
    用Windbg来分析.Net程序的dump
    Windows下docker的安装,将ASP.NET Core程序部署在Linux和Docker中
    StackExchange.Redis学习笔记(五) 发布和订阅
    StackExchange.Redis学习笔记(四) 事务控制和Batch批量操作
    StackExchange.Redis学习笔记(三) 数据库及密码配置 GetServer函数
    StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用
    Task及Mvc的异步控制器 使用探索
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7225769.html
Copyright © 2020-2023  润新知