彻底搞懂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.

由上面的执行计划可以知道,b表执行2次,返回2行

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.

由上面的执行计划可以知道,b表执行3次,返回2行

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.

由上面的执行计划可以知道,b表执行9次,返回2行

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.

由上面的执行计划可以知道,b表执行2次,返回2行

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.

b.name字段全部为‘b1’,由上面的执行计划可以知道,b表执行9次,返回9行

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>

关联字段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次。

彻底搞懂oracle的标量子查询,布布扣,bubuko.com

时间: 2024-12-23 12:16:51

彻底搞懂oracle的标量子查询的相关文章

Oracle sql优化之分析函数优化标量子查询

待优化语句如下 select a.code as code, a.m_code as m_code,a.stktype as f_stype,a.e_year as e_year, b.sname as sname,a.c_date as c_date,to_char(sysdate,'YYYYMMDD') as createtime, to_char(sysdate,'YYYYMMDD') as updatetime, (select sum(valuef2) from a t where t

oracle标量子查询

SQL> conn scott/scott Connected. 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

SQL Server的优化器会缓存标量子查询结果集吗

在这篇博客"ORACLE当中自定义函数性优化浅析"中,我们介绍了通过标量子查询缓存来优化函数性能: 标量子查询缓存(scalar subquery caching)会通过缓存结果减少SQL对函数(Function)的调用次数, ORACLE会在内存中构建一个哈希表来缓存标量子查询的结果. 那么SQL Server的优化器是否也会有类似这样的功能呢? 抱着这样的疑问,动手测试了一下,准备测试环境 CREATE TABLE TEST (    ID  INT );     DECLARE

优化有标量子查询的SQL

数据库环境:SQL SERVER 2008R2 今天在数据库中抓出一条比较耗费资源的SQL,只返回904条数据,居然跑了40多分钟.SQL及对应的数据量如下图: SELECT saft04.cur_year , LEFT(saft04.dept_id, 4) sdept_id , saft04.vdept_id , saft04.dept_id , saft04.fee_id , saft04.vitem_id , ISNULL(saft04.fee_amt, 0) AS saft04_fee_

[转]Oracle DB 使用子查询来解决查询

? 定义子查询 ? 描述子查询可以解决的问题类型 ? 列出子查询的类型 ? 编写单行和多行子查询 ? 子查询:类型.语法和准则 ? 单行子查询: – 子查询中的组函数 – 带有子查询的HAVING子句 ? 多行子查询 – 使用ALL或ANY运算符 ? 使用EXISTS运算符 ? 子查询中的空值 使用子查询解决问题 谁的薪金高于Abel 的薪金? 子查询: Abel 的薪金是多少? 主查询: 哪些雇员的薪金高于Abel 的薪金? 使用子查询解决问题 假设要编写一个查询来找出谁的薪金高于Abel 的

标量子查询

--标量子查询select e.empno, e.ename, e.sal, e.deptno,       (select d.dname from dept d where e.deptno = d.deptno)as dname  from emp e--插入一条数据insert into emp(empno,deptno) values(9999,null)--返回结果15条记录--改成left join(hash outer)select e.empno, e.ename, e.sal

mysql 标量子查询和非法子查询

#where或having后面:#标量子查询(单行子查询)#列子查询(多行子查询)#行子查询(多行多列) 特点:子查询放在小括号内,一般放在条件的右侧,标量子查询一般配备单行操作符使用单行操作符:<> >= <= < >列子查询:一般搭配着多行操作符使用多行操作符:in.any.some.all #标量子查询#案例:谁的工资比ABEL高的员工信息 SELECT * FROM employees WHERE salary>( SELECT salary FROM e

你搞懂 ORACLE、 SQLSERVER、MYSQL与DB2的区别了吗

ORACLE. SQLSERVER.MYSQL与DB2的区别--平台性:    Oracle.MYSQL与DB2可在所有主流平台上运行:    SQL Server只能在Windows下运行: --安全性:    Oracle的安全认证获得最高认证级别的ISO标准认证,而SQL Server并没有获得什么安全认证:    这方面证明了Oracle的安全性是高于SQL Server的: --数据类型.函数.sql语句:    oracle中有复合数据类型,sql server中没有: 总之:   

Oracle with重用子查询

--with 重用子查询对于多次使用相同子查询的复杂查询语句来说,用户可能会将查询语句分成两条语句执行.第一条语句将子查询结果存放到临时表,第二条查询语句使用临时表处理数据.从 Oracle 9i 开始,通过 with 子句可以给予子查询指定一个名称,并且使得在一条语句中可以完成所有任务,从而避免了使用临时表. [email protected] test10g> with summary as (  2  select dname, sum(sal) dept_total from emp,