Professional Documents
Culture Documents
杨廷琨
云和恩墨成就所托
云和恩墨 成就所托
个人介绍
杨廷琨(yangtingkun)
Oracle ACE Director
ITPUB数据库管理区版主
ACOUG核心会员副总裁
参与编写《Oracle数据库性能优化》、
《Oracle DBA手记》、《Oracle DBA手记3》
和 《 Oracle性能优化与诊断案例精选》
十九年的一线DBA经验
个人BLOG中积累了2500篇原创技术文章
云和恩墨CTO
云和恩墨成就所托
云和恩墨 成就所托
内容
⚫ 培训包含:
• SQL
⚫ 培训不含:
• 范式设计
• 物理建模
• SQL语法
• 索引结构
• 数据库优化
⚫ 运行环境
• CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM
DBA_OBJECTS A;
云和恩墨成就所托
云和恩墨 成就所托
高效SQL的必要性
⚫ SQL是世界上第二大的编程语言,超过50%的开发
者使用SQL
⚫ 80%的数据库问题是SQL引起的
⚫ 80%的性能问题来自20%的SQL语句
⚫ 高并发环境中,单条SQL语句可能导致整个数据库
出现性能故障
云和恩墨成就所托
云和恩墨 成就所托
YUNHE ENMO (BEIJING) TECHNOLOGY CO.,LTD
1 合理运用新特性
2 数据集整体处理
3 设计SQL执行计划
4 严格过滤数据
云和恩墨 成就所托
合理运用新特性
目标:从一张表取数据插入到另一张表中,此外需要
为插入的目标表做一个应用级的日志表,也就是说在
插入目标表的同时,还需要将相同的数据插入到日志
表中。
T_TAR
T_ORG
T_LOG
云和恩墨成就所托
云和恩墨 成就所托
合理运用新特性
方案:
⚫ CREATE TRIGGER
方案:
⚫ CREATE TRIGGER
• 太“重”
• 实现与需求有差异
• 增加后续维护成本
• 触发器效率较低
云和恩墨成就所托
云和恩墨 成就所托
合理运用新特性
方案:
⚫ CREATE TRIGGER
⚫ DOUBLE INSERT
云和恩墨成就所托
云和恩墨 成就所托
合理运用新特性
方案:
⚫ CREATE TRIGGER
⚫ DOUBLE INSERT
• 一致性
➢ 锁
➢ 串行事务
➢ 临时表
➢ AS OF查询
• 原子性
➢ 异常处理
云和恩墨成就所托
云和恩墨 成就所托
合理运用新特性
方案:
⚫ CREATE TRIGGER
⚫ DOUBLE INSERT
⚫ OPEN CURSOR
SQL> BEGIN
2 FOR I IN (SELECT * FROM T_ORG) LOOP
3 INSERT INTO T_TAR VALUES (I.ID, I.NAME);
4 INSERT INTO T_LOG VALUES (I.ID, I.NAME);
5 END LOOP;
6 END;
7 /
PL/SQL 过程已成功完成。
云和恩墨成就所托
云和恩墨 成就所托
合理运用新特性
方案:
⚫ CREATE TRIGGER
⚫ DOUBLE INSERT
⚫ OPEN CURSOR
⚫ 效率低
云和恩墨成就所托
云和恩墨 成就所托
合理运用新特性
方案:
⚫ CREATE TRIGGER
⚫ DOUBLE INSERT
⚫ OPEN CURSOR
⚫ BULK INTO VARIABLE
云和恩墨成就所托
云和恩墨 成就所托
合理运用新特性
SQL> DECLARE
2 TYPE T_ID IS TABLE OF T_ORG.ID%TYPE;
3 TYPE T_NAME IS TABLE OF T_ORG.NAME%TYPE;
4 V_ID T_ID;
5 V_NAME T_NAME;
6 BEGIN
7 SELECT ID, NAME BULK COLLECT INTO V_ID, V_NAME
8 FROM T_ORG;
9 FORALL I IN 1..V_ID.COUNT
10 INSERT INTO T_TAR VALUES(V_ID(I), V_NAME(I));
11 FORALL I IN 1..V_ID.COUNT
12 INSERT INTO T_LOG VALUES(V_ID(I), V_NAME(I));
13 END;
14 /
PL/SQL 过程已成功完成。
云和恩墨成就所托
云和恩墨 成就所托
合理运用新特性
方案:
⚫ CREATE TRIGGER
⚫ DOUBLE INSERT
⚫ OPEN CURSOR
⚫ BULK INTO VARIABLE
• 复杂度高
• 效率较低
云和恩墨成就所托
云和恩墨 成就所托
合理运用新特性
方案:
⚫ CREATE TRIGGER
⚫ DOUBLE INSERT
⚫ OPEN CURSOR
⚫ BULK INTO VARIABLE
⚫ INSERT ALL
云和恩墨成就所托
云和恩墨 成就所托
WITH语句
列出T表中用户包含对象数量大于平均用户对象数的记录
SQL> SELECT OWNER, COUNT(*) CN
2 FROM T
3 GROUP BY OWNER
4 HAVING COUNT(*) >
5 (SELECT AVG(COUNT(*)) FROM T GROUP BY OWNER);
OWNER CN
------------------------------ ----------
PUBLIC 37071
SYS 42068
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 12 | 452 (2)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | HASH GROUP BY | | 2 | 12 | 452 (2)| 00:00:01 |
| 3 | TABLE ACCESS FULL | T | 91168 | 534K| 445 (1)| 00:00:01 |
| 4 | SORT AGGREGATE | | 1 | 6 | 452 (2)| 00:00:01 |
| 5 | SORT GROUP BY | | 1 | 6 | 452 (2)| 00:00:01 |
| 6 | TABLE ACCESS FULL| T | 91168 | 534K| 445 (1)| 00:00:01 |
-----------------------------------------------------------------------------
云和恩墨成就所托
云和恩墨 成就所托
WITH语句
SQL> WITH A AS
2 (SELECT OWNER, COUNT(*) CN FROM T GROUP BY OWNER)
3 SELECT A.*
4 FROM A, (SELECT AVG(CN) ACN FROM A) B
5 WHERE A.CN > B.ACN;
OWNER CN
------------------------------ ----------
PUBLIC 37071
SYS 42068
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 92 | 456 (2)|
| 1 | TEMP TABLE TRANSFORMATION | | | | |
| 2 | LOAD AS SELECT | SYS_TEMP_0FD9D6633_DE0CE4 | | | |
| 3 | HASH GROUP BY | | 26 | 156 | 452 (2)|
| 4 | TABLE ACCESS FULL | T | 91168 | 534K| 445 (1)|
| 5 | NESTED LOOPS | | 1 | 92 | 4 (0)|
| 6 | VIEW | | 1 | 13 | 2 (0)|
| 7 | SORT AGGREGATE | | 1 | 13 | |
| 8 | VIEW | | 26 | 338 | 2 (0)|
| 9 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6633_DE0CE4 | 26 | 156 | 2 (0)|
|* 10 | VIEW | | 1 | 79 | 2 (0)|
| 11 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6633_DE0CE4 | 26 | 156 | 2 (0)|
---------------------------------------------------------------------------------------------
云和恩墨成就所托
云和恩墨 成就所托
ANALYTIC FUNCTIONS
以用户名和对象名称来判断重复记录,列出重复的记录:
SQL> SELECT OWNER, OBJECT_NAME
2 FROM T
3 WHERE OWNER = 'TEST'
4 AND ROWID NOT IN (
5 SELECT MAX(ROWID)
6 FROM T
7 WHERE OWNER = 'TEST'
8 GROUP BY OWNER, OBJECT_NAME)
9 ORDER BY 1, 2;
OWNER OBJECT_NAME
------------------------------ ----------------------------------------
TEST T_PART
TEST T_PART
TEST T_PART
TEST T_PART
……
TEST T_PART2
TEST T_PART2
云和恩墨成就所托
云和恩墨 成就所托
ANALYTIC FUNCTIONS
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2644 | 139K| 808 (1)| 00:00:01 |
| 1 | SORT ORDER BY | | 2644 | 139K| 808 (1)| 00:00:01 |
|* 2 | HASH JOIN RIGHT ANTI| | 2644 | 139K| 807 (1)| 00:00:01 |
| 3 | VIEW | VW_NSO_1 | 1891 | 22692 | 404 (1)| 00:00:01 |
| 4 | HASH GROUP BY | | 1891 | 79422 | 404 (1)| 00:00:01 |
|* 5 | TABLE ACCESS FULL| T | 2697 | 110K| 403 (1)| 00:00:01 |
|* 6 | TABLE ACCESS FULL | T | 2697 | 110K| 403 (1)| 00:00:01 |
----------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2902 consistent gets
0 physical reads
0 redo size
3015 bytes sent via SQL*Net to client
611 bytes received via SQL*Net from client
10 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
132 rows processed
云和恩墨成就所托
云和恩墨 成就所托
ANALYTIC FUNCTIONS
SQL> SELECT OWNER, OBJECT_NAME
2 FROM (
3 SELECT OWNER, OBJECT_NAME,
4 ROW_NUMBER() OVER(PARTITION BY OWNER, OBJECT_NAME ORDER BY ROWID DESC) RN
5 FROM T
6 WHERE OWNER = 'TEST')
7 WHERE RN > 1
8 ORDER BY 1, 2;
OWNER OBJECT_NAME
------------------------------ ----------------------------------------
TEST T_PART
TEST T_PART
TEST T_PART
TEST T_PART
……
TEST T_PART2
TEST T_PART2
云和恩墨成就所托
云和恩墨 成就所托
ANALYTIC FUNCTIONS
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2697 | 252K| 404 (1)| 00:00:01 |
|* 1 | VIEW | | 2697 | 252K| 404 (1)| 00:00:01 |
| 2 | WINDOW SORT | | 2697 | 110K| 404 (1)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| T | 2697 | 110K| 403 (1)| 00:00:01 |
----------------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
1451 consistent gets
0 physical reads
0 redo size
3015 bytes sent via SQL*Net to client
611 bytes received via SQL*Net from client
10 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
132 rows processed
云和恩墨成就所托
云和恩墨 成就所托
TOP-N语句
按照对象ID排序,取第21条到30条记录:
SQL> SELECT OBJECT_ID, OBJECT_NAME FROM
2 (SELECT ROWNUM RN, A.* FROM
3 (SELECT OBJECT_ID, OBJECT_NAME FROM T
4 ORDER BY OBJECT_ID) A
5 WHERE ROWNUM <= 30)
6 WHERE RN > 20;
OBJECT_ID OBJECT_NAME
---------- ----------------------------------------------
22 USER$
23 PROXY_DATA$
24 I_PROXY_DATA$
25 PROXY_ROLE_DATA$
26 I_PROXY_ROLE_DATA$_1
27 I_PROXY_ROLE_DATA$_2
28 CON$
29 C_COBJ#
30 I_COBJ#
31 CDEF$
云和恩墨成就所托
云和恩墨 成就所托
TOP-N语句
OBJECT_ID OBJECT_NAME
---------- ----------------------------------
22 USER$
23 PROXY_DATA$
24 I_PROXY_DATA$
25 PROXY_ROLE_DATA$
26 I_PROXY_ROLE_DATA$_1
27 I_PROXY_ROLE_DATA$_2
28 CON$
29 C_COBJ#
30 I_COBJ#
31 CDEF$
云和恩墨成就所托
云和恩墨 成就所托
TOP-N语句
OBJECT_ID OBJECT_NAME
---------- -----------------------------------------------------------------------------
22 USER$
23 PROXY_DATA$
24 I_PROXY_DATA$
25 PROXY_ROLE_DATA$
26 I_PROXY_ROLE_DATA$_1
27 I_PROXY_ROLE_DATA$_2
28 CON$
29 C_COBJ#
30 I_COBJ#
31 CDEF$
云和恩墨成就所托
云和恩墨 成就所托
合理运用新特性
新特性:
⚫ INSERT ALL/ANY 插入多张表或限定条件插入
⚫ MERGE 合并UPDATE和INSERT语句
⚫ WITH 避免重复读取
⚫ ANALYTIC FUNCTIONS 行级计算避免自关联
⚫ TOP-N 分页语句
⚫ PIVOT/UNPIVOT 行列转换
⚫ MODEL 报表数组处理
⚫ PATTERN 模式匹配查询
云和恩墨成就所托
云和恩墨 成就所托
云和恩墨成就所托
云和恩墨 成就所托 云和恩墨 成就所托