[20150727]使用标量子查询小问题.txt

[20150727]使用标量子查询小问题.txt

--最近一段时间一直在做优化,仔细看我前面的blog,不主张使用标量子查询,实际上还是有一些小细节要注意。

1.测试环境:
SCOTT@test> @ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.3.0     Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

SCOTT@test> alter session set statistics_level=all;
Session altered.

2.开始测试:

SCOTT@test> select emp.*,(select dname from dept where dept.deptno=emp.deptno) dname from emp ;
     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO DNAME
---------- ---------- --------- ---------- ------------------- ---------- ---------- ---------- --------------
      7369 SMITH      CLERK           7902 1980-12-17 00:00:00        800                    20 RESEARCH
      7499 ALLEN      SALESMAN        7698 1981-02-20 00:00:00       1600        300         30 SALES
      7521 WARD       SALESMAN        7698 1981-02-22 00:00:00       1250        500         30 SALES
      7566 JONES      MANAGER         7839 1981-04-02 00:00:00       2975                    20 RESEARCH
      7654 MARTIN     SALESMAN        7698 1981-09-28 00:00:00       1250       1400         30 SALES
      7698 BLAKE      MANAGER         7839 1981-05-01 00:00:00       2850                    30 SALES
      7782 CLARK      MANAGER         7839 1981-06-09 00:00:00       2450                    10 ACCOUNTING
      7788 SCOTT      ANALYST         7566 1987-04-19 00:00:00       3000                    20 RESEARCH
      7839 KING       PRESIDENT            1981-11-17 00:00:00       5000                    10 ACCOUNTING
      7844 TURNER     SALESMAN        7698 1981-09-08 00:00:00       1500          0         30 SALES
      7876 ADAMS      CLERK           7788 1987-05-23 00:00:00       1100                    20 RESEARCH
      7900 JAMES      CLERK           7698 1981-12-03 00:00:00        950                    30 SALES
      7902 FORD       ANALYST         7566 1981-12-03 00:00:00       3000                    20 RESEARCH
      7934 MILLER     CLERK           7782 1982-01-23 00:00:00       1300                    10 ACCOUNTING
14 rows selected.

SCOTT@test> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  572663gdmp3jm, child number 0
-------------------------------------
select emp.*,(select dname from dept where dept.deptno=emp.deptno)
dname from emp
Plan hash value: 2981343222
---------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |      1 |        |       |     3 (100)|          |     14 |00:00:00.01 |       7 |
|   1 |  TABLE ACCESS BY INDEX ROWID| DEPT    |      3 |      1 |    13 |     1   (0)| 00:00:01 |      3 |00:00:00.01 |       5 |
|*  2 |   INDEX UNIQUE SCAN         | PK_DEPT |      3 |      1 |       |     0   (0)|          |      3 |00:00:00.01 |       2 |
|   3 |  TABLE ACCESS FULL          | EMP     |      1 |     14 |   532 |     3   (0)| 00:00:01 |     14 |00:00:00.01 |       7 |
---------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$2 / DEPT@SEL$2
   2 - SEL$2 / DEPT@SEL$2
   3 - SEL$1 / EMP@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("DEPT"."DEPTNO"=:B1)

--可以发现id=2,starts = 3,总的buffers=5,总共12个逻辑读。(注:不知道为什么少1次,共3次,每次2个逻辑读,应该是6.我的理解。)

3.继续测试:
SCOTT@test> create table empx as select * from emp ;
Table created.

SCOTT@test> update empx set deptno=20 ;
14 rows updated.

SCOTT@test> commit ;
Commit complete.

--换成empx继续测试:
SCOTT@test> select empx.*,(select dname from dept where dept.deptno=empx.deptno) dname from empx ;
     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO DNAME
---------- ---------- --------- ---------- ------------------- ---------- ---------- ---------- --------------
      7369 SMITH      CLERK           7902 1980-12-17 00:00:00        800                    20 RESEARCH
      7499 ALLEN      SALESMAN        7698 1981-02-20 00:00:00       1600        300         20 RESEARCH
      7521 WARD       SALESMAN        7698 1981-02-22 00:00:00       1250        500         20 RESEARCH
      7566 JONES      MANAGER         7839 1981-04-02 00:00:00       2975                    20 RESEARCH
      7654 MARTIN     SALESMAN        7698 1981-09-28 00:00:00       1250       1400         20 RESEARCH
      7698 BLAKE      MANAGER         7839 1981-05-01 00:00:00       2850                    20 RESEARCH
      7782 CLARK      MANAGER         7839 1981-06-09 00:00:00       2450                    20 RESEARCH
      7788 SCOTT      ANALYST         7566 1987-04-19 00:00:00       3000                    20 RESEARCH
      7839 KING       PRESIDENT            1981-11-17 00:00:00       5000                    20 RESEARCH
      7844 TURNER     SALESMAN        7698 1981-09-08 00:00:00       1500          0         20 RESEARCH
      7876 ADAMS      CLERK           7788 1987-05-23 00:00:00       1100                    20 RESEARCH
      7900 JAMES      CLERK           7698 1981-12-03 00:00:00        950                    20 RESEARCH
      7902 FORD       ANALYST         7566 1981-12-03 00:00:00       3000                    20 RESEARCH
      7934 MILLER     CLERK           7782 1982-01-23 00:00:00       1300                    20 RESEARCH
14 rows selected.

SCOTT@test> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  56k9g55sap2h9, child number 0
-------------------------------------
select empx.*,(select dname from dept where dept.deptno=empx.deptno)
dname from empx
Plan hash value: 3630249127
---------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |      1 |        |       |     3 (100)|          |     14 |00:00:00.01 |       3 |
|   1 |  TABLE ACCESS BY INDEX ROWID| DEPT    |      1 |      1 |    13 |     1   (0)| 00:00:01 |      1 |00:00:00.01 |       2 |
|*  2 |   INDEX UNIQUE SCAN         | PK_DEPT |      1 |      1 |       |     0   (0)|          |      1 |00:00:00.01 |       1 |
|   3 |  TABLE ACCESS FULL          | EMPX    |      1 |     14 |   532 |     3   (0)| 00:00:01 |     14 |00:00:00.01 |       3 |
---------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$2 / DEPT@SEL$2
   2 - SEL$2 / DEPT@SEL$2
   3 - SEL$1 / EMPX@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("DEPT"."DEPTNO"=:B1)

--可以发现id=2,starts =1,总的buffers=2,总共5个逻辑读。如果标量查询每次返回都一样,oracle仅仅执行1次。逻辑读一样很小。

--至少说明一点如果标量子查询的变化很少,总的逻辑读不会太高。当然我个人坚持认为尽量少用标量子查询,它有许多限制,主要是开
--发许多不了解oracle。

时间: 2024-09-20 10:40:58

[20150727]使用标量子查询小问题.txt的相关文章

[20140125]关于标量子查询.txt

  最近一致在优化一个垃圾项目,我发现一个奇怪的想象,就是开发很喜欢使用标量子查询,我发现这个东西像传染病一样,一个人使用其 他人也跟着仿效,而不考虑具体的使用场合.还有一些出现在视图里面. 我想通过一些例子来说明情况: @ver BANNER                                                                               CON_ID ------------------------------------------

性能为王:SQL标量子查询的优化案例分析

黄廷忠(网名:认真就输) 云和恩墨技术专家 个人博客:http://www.htz.pw/ 本篇整理内容是黄廷忠在"云和恩墨大讲堂"微信分享中的讲解案例,SQL优化及SQL审核,是从源头解决性能问题的根本手段,无论是开发人员还是DBA,都应当持续深入的学习SQL开发技能,从而为解决性能问题打下根基. 本篇为系列案例之一:标量子查询优化   以下案例来自于某省电信系统EDW性能优化实践,数据库版本为11.2.0.3,运行在ORACLE Exadata一体机上,是个典型的OLAP环境,表上

在MySQL中使用子查询和标量子查询的基本操作教程_Mysql

MySQL 子查询子查询是将一个 SELECT 语句的查询结果作为中间结果,供另一个 SQL 语句调用.MySQL 支持 SQL 标准要求的所有子查询格式和操作,也扩展了特有的几种特性. 子查询没有固定的语法,一个子查询的例子如下: SELECT * FROM article WHERE uid IN(SELECT uid FROM user WHERE status=1) 对应的两个数据表如下: article 文章表: user 用户表: 查询返回结果如下所示: 在该例子中,首先通过子查询语

SQL为王:oracle标量子查询和表连接改写

小鱼(邓秋爽) 云和恩墨专家,有超过5年超大型数据库专业服务经验,擅长oracle 数据库优化.SQL优化和troubleshooting 编辑手记:如何提高数据的查询效率是每个人都关注的问题,今天让我们来学习如何合理使用标量子查询和表连接方式来提高查询速度吧~ 之前小鱼就听过了标量子查询,不过对于其中的细节理解还是远远不够,借助一部分资料和自己测试对标量子查询做一点简单的分析和介绍. Oracle允许在select子句中包含单行子查询,这个也就是oracle的标量子查询,标量子查询有点类似于外

都是标量子查询惹的祸

都是标量子查询惹的祸 系统又报了一个跑的慢的sql语句,看图就知道这个很恐怖的,已经跑了1天了,还需要跑6个月的时间,   把sql语句拿出来瞅瞅: --201406 XX select SUM(UNPOSTING_AMT_CYC) 分期未结清余额, SUM(greatest(nvl(BAL_TOTAL,0),0)) 余额,COUNT(1),DELQ_LEVEL_CI,city,FQ_TOTAL, CASE WHEN greatest(nvl(BAL_TOTAL,0),0) 500 THEN '

一道Oracle子查询小练习

昨天晚上躺在床上看Oracle(最近在学习这个),室友说出个题目让我试试.题目如下: 有如下表结构,请选择出成绩为前三名的人的信息(如果成绩相同,则算并列),表名为test: NAME                      GRADE -------------------- ---------- kate                            80 jenny                          80 daring                       

详细讲述MySQL中的子查询操作_Mysql

继续做以下的前期准备工作:     新建一个测试数据库TestDB:     create database TestDB;     创建测试表table1和table2: CREATE TABLE table1 ( customer_id VARCHAR(10) NOT NULL, city VARCHAR(10) NOT NULL, PRIMARY KEY(customer_id) )ENGINE=INNODB DEFAULT CHARSET=UTF8; CREATE TABLE table

SQL Server高级内容之子查询和表链接概述及使用_MsSql

1.子查询概念 (1)就是在查询的where子句中的判断依据是另一个查询的结果,如此就构成了一个外部的查询和一个内部的查询,这个内部的查询就是自查询. (2)自查询的分类 1)独立子查询 ->独立单值(标量)子查询(=) 复制代码 代码如下: Select testID,stuID,testBase,testBeyond,testPro from Score where stuID=( select stuID from Student where stuName='Kencery' ) ->

【MySQL】子查询之一

MySQL 从版本4 开始支持 SQL 标准要求的所有子查询格式和操作,同时扩展了特有的几种特性.本文会介绍子查询的类型以及相关的注意点. 一 什么是子查询     子查询是将一个 SELECT 语句的查询结果作为中间结果,供另一个 SQL 语句调用.如: SELECT * FROM t1  WHERE vid in  (SELECT  vid FROM t2); 二 MySQL 子查询分类       根据子查询的返回数据形式,mysql 子查询可以分为以下几类: a  标量子查询