altibase管理培训 优化篇 v1.1

49
ALTIBASE 管管管管 优优优

Upload: -

Post on 26-Jan-2015

229 views

Category:

Documents


7 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Altibase管理培训 优化篇 v1.1

ALTIBASE 管理培训优化篇

Page 2: Altibase管理培训 优化篇 v1.1

CONTENTS1. Tuning 概要2. ALTIBASE 架构3. 诊断方法4. Explain Plan5. Query Tuning

Page 3: Altibase管理培训 优化篇 v1.1

Tuning Tuning 概要概要1. 数据库发展方向2. 影响数据库性能的几个问题3. 提高性能的要素4. ALTIBASE Performance Tuning

Page 4: Altibase管理培训 优化篇 v1.1

1970 年代之前 : 以文件形式管理数据

1970 年代 : 开始出现数据库管理系统

1980 年代 : 关系型数据库的商用化

1990 年代 : 国内开始引进并使用数据库

2000 年代 : 内存数据库的商用化

现在 : 同时满足大容量和高性能处理的融合数据库

数据库的发展方向

Page 5: Altibase管理培训 优化篇 v1.1

产出物为主的开发

有限的项目费用和开发工期

开发人员对数据库知识的不足

不适当的硬件和数据库的评估

对项目以及技术的自信心

影响数据库性能的几个问题

Page 6: Altibase管理培训 优化篇 v1.1

适合于关系型数据库的系统设计

通过资深系统分析架构师的引导降低项目风险

确保熟悉 SQL 的应用开发人员

提高性能的要素

Page 7: Altibase管理培训 优化篇 v1.1

2. 应用程序优化

3. SQL 优化

4. 操作系统优化

5. 数据库参数优化1. 系统设计优化

Tuning Steps

ALTIBASE Performance Tuning

Page 8: Altibase管理培训 优化篇 v1.1

执行计划

表结构和数据量 ( 索引、数据类型 )

应用的逻辑 ( 访问表的顺序和次数 )

系统资源的有效使用 (CPU 和 Memory)

Tuning 要素

ALTIBASE Performance Tuning

Page 9: Altibase管理培训 优化篇 v1.1

ALTIBASEALTIBASE 架构架构1. ALTIBASE 结构2. SELECT 处理过程3. DML 处理过程 4. COMMIT 处理过程5. 逻辑存储结构

Page 10: Altibase管理培训 优化篇 v1.1

Physical Memory

Integrated Storage ManagerIntegrated Storage Manager

Recovery Manager

Buffer Manager

Integrated Query ProcessorIntegrated Query Processor

Parser Optimizer Executor

IndexManager

E/SQL CLI ODBC JDBC

IPC Unix Domain Socket TCP/IP

Transaction Manager

Stable Storage

Checkpoint Image

Log Buffer Disk BufferMemory Tablespace

Stable Log Disk Tablespace

Application

ALTIBASE 结构

Page 11: Altibase管理培训 优化篇 v1.1

Optimization

Validation

Parsing

Execution

syntax check generate Parsing Tree

semantic check access META

calculate cost / normalize generate Execution Plan Tree

execute Execution Plan tree access table

Table Log Lock Index Transc. Memory GC

Storage Manager

SQL TextSQL Text

SELECT 处理过程

Page 12: Altibase管理培训 优化篇 v1.1

ALTIBASE 支持 MVCC MVCC(Multi-Version Concurrency Control) 并发控制。变更操作时,生成新版本记录再获得锁,所以读 / 写操作之间不发生冲突,并保证复杂事务环境下的高性能。

Garbage Collection

一旦更新事务被提交,多个记录版本中只有最后生成的版本信息有效,而且旧版本被垃圾收集器删除,回收的槽被插入 / 更新操作再利用,以提高内存的使用率。

曹操 34 刘备 34

select DML

生成新版本

Exclusive ModeExclusive Mode

Transaction 1 Transaction 3

曹操 34

Exclusive ModeExclusive Mode

TX 2TX 1

TX 3

DMLselect

SVCC 方式Transaction 2

DML 处理过程

Page 13: Altibase管理培训 优化篇 v1.1

刘备

曹操 曹操 刘备

Out-Place ( 变更 RID) In-Place ( 维持 RID)

Data Page Data Page Undo Area

OLD

NEW

OLDNEW

Memory Tables 内存表是在数据页中对新版本的记录以另一个 RID 存储的 Out-place 结构以确保高性能为了有效使用数据页,当新版本记录大小大于 property 指定(LOCK_ESCALATION_MEMORY_SIZE) 的大小时自动转换为 In-place Update 。

Disk Tables 磁盘表采用对于变更的记录字段以 Undo log 记录存储于 Undo 表空间用变更后的数据覆盖源数据的 In-place 结构。

DML 处理过程

Page 14: Altibase管理培训 优化篇 v1.1

Logging : 为了恢复已提交的事务,处理事务时记录日志 Checkpoint: 日志文件个数达到一定个数或周期达到设定的时间时把更新的内存数据页写到磁盘以缩短恢复时间

数据页储存数据并返回事务结果前以文件形式记录 (logging) 事务的内容 非正常时内存上的数据即使发生了流失,也可通过文件系统上的日志文件可以恢复数据

WAL(Write Ahead Logging)

LogArch

TX

1

DB in Memory

Log Buffer in Memory

LogSync

22 25

Checkpoint

Data File

Archive Log File

Online Log File

3

Commit

24

COMMIT 处理过程

Page 15: Altibase管理培训 优化篇 v1.1

下面是 ALTIBASE 建议使用的应用程序组织方式

SQL预处理

SQL执行

获取(Fetch)数据

提交(或回滚)事务

SQLPrepare

SQLBindParameter

SQLExecute

SQLFetch

SQLEndTran

数据记录循环操作

初始化资源SQLAllocHandle(STMT)

建立连接

SQLAllocHandle(ENV)

SQLSetEnvAttr

SQLAllocHandle(DBC)

SQLSetConnectAttr

释放连接

SQLFreeHandle(STMT)

SQLDisconnect

SQLFreeHandle(DBC)

SQLFreeHandle(ENV)

释放语句句柄

SQLDrop

SQLAllocStmt

SQLDescribeCol

SQLBindCol

释放阶段

SQLDriverConnect

SQLSetStmtAttr

初始化阶段

ALTIBASE ODBC 应用优化

Page 16: Altibase管理培训 优化篇 v1.1

Database 文件系统 Structure

DATABASE File SystemDATABASE File System

TABLESPACE A TABLESPACE B TABLESPACE C

DATAFILE 1

1 DATAFILE 2

2 DATAFILE 3

DATAFILE 4

4 DATAFILE 5

5 DATAFILE 6

DATAFILE 7

7 DATAFILE 8

8 DATAFILE 9

逻辑存储结构 (Database)

Page 17: Altibase管理培训 优化篇 v1.1

表空间 Structure

Tablespace

Table Index

Extent

Used Page

Free Page

Segment

* 表空间分类– 内存表空间 (SYS_TBS_MEMORY)

• 数据字典 , 内存表– 数据表空间

• 系统表空间 (SYS_TBS_DATA)• 用户表空间

– Undo 表空间 (SYS_TBS_UNDO)• 为了多版本并发控制,存储变更

前的映像– 临时表空间

• 系统临时表空间(SYS_TBS_TEMP)

• 用户临时表空间– 扩展名 .dbf

逻辑存储结构 (TableSpace)

Page 18: Altibase管理培训 优化篇 v1.1

INDEX 使用注意事项• 并不是所有的情况下,使用索引访问都能加快速度。 • 索引的可选择性非常重要。当索引的可选择性比较高(具有相同值的行很少),而我们需要数据量又比较小的时候,索引才能极大的提高数据访问的速度。当索引的可选择性比较差的时候,而我们使用的数据量又比较大,此时,使用索引反而会使查询的速度变慢。• 针对索引的列,需要匹配索引列的类型,也不能在其上使用计算、函数等操作,否则,会使索引失效。• 索引的维护需要成本,会带来 DML 的效率降低。所以只有在需要的时候才能去创建索引。

INDEX

Page 19: Altibase管理培训 优化篇 v1.1

INDEX 使用注意事项 • 当一个表上存在多个索引,只能使用这个表上的一个索引。 ( 具体使用哪一个索引由 Altibase 优化器决定 )

SELECT Y.ENAMEFROM EMPLOYEE X WHERE X.ENO = 8890 AND X.ENAME = ‘MSKIM’

SELECT Y.ENAMEFROM EMPLOYEE X WHERE X.ENO = 8890 AND X.ENAME = ‘MSKIM’

ENO 上存在索引 IDX_EMP1 , ENAME 上存在索引 IDX_EMP2 ,当我们访问表 EMPLOYEE 的时候,优化器只会选择 IDX_EMP1, IDX_EMP2 中的一个进行访问。

ENO 上存在索引 IDX_EMP1 , ENAME 上存在索引 IDX_EMP2 ,当我们访问表 EMPLOYEE 的时候,优化器只会选择 IDX_EMP1, IDX_EMP2 中的一个进行访问。

INDEX

Page 20: Altibase管理培训 优化篇 v1.1

How Index Works (Using unique index)

SELECT * FROM EMPLOYEE WHERE ENO = 1;SELECT * FROM EMPLOYEE WHERE ENO = 1;

ENO 是表的 PRIMARY KEY, PRIMARY KEY 是非空唯一索引。

ENO 是表的 PRIMARY KEY, PRIMARY KEY 是非空唯一索引。

INDEX

Page 21: Altibase管理培训 优化篇 v1.1

How Index Works (Using unique index)

__SYS_IDX_ID_403(INDEX)

__SYS_IDX_ID_403(INDEX)

EMPLOYEE(TABLE)

EMPLOYEE(TABLE)

QueryProcessor

QueryProcessor

-索引是有序存放的,表中的数据是无序存放的。-索引查询的时候首先会访问 B树索引的根节点,再根据根节点找到索引的叶子节点(叶子节点中存放直接指向表数据行的指针)。-根据叶子节点的指针,直接读到表的数据行。

SortedSorted Not Sorted Not Sorted

INDEX

Page 22: Altibase管理培训 优化篇 v1.1

How Index Works (Using non unique index)

SELECT * FROM EMPLOYEE WHERE DNO = 1003;SELECT * FROM EMPLOYEE WHERE DNO = 1003;

Department – Employee 是1 对多的关系,所以 Employee 表的 DNO 字段会存在重复的数据。

Department – Employee 是1 对多的关系,所以 Employee 表的 DNO 字段会存在重复的数据。

INDEX

Page 23: Altibase管理培训 优化篇 v1.1

How Index Works (Using non unique index)

EMP_IDX1(INDEX)

EMP_IDX1(INDEX)

EMPLOYEE(TABLE)

EMPLOYEE(TABLE)

QueryProcessor

QueryProcessor

-假如查找 DNO 为 1003 的行。根据索引的叶子节点,会得到两个指向到 EMPLOYEE 表的指针。-根据这两个指针,就可以读取到 EMPLOYEE 表的两行数据。

SortedSorted Not Sorted Not Sorted

INDEX

Page 24: Altibase管理培训 优化篇 v1.1

How Index Works (Index scan fail)

SELECT * FROM EMPLOYEE WHERE UPPER(DNO) = ‘1’;SELECT * FROM EMPLOYEE WHERE UPPER(DNO) = ‘1’;

对 ENO 列使用函数 UPPER 。对 ENO 列使用函数 UPPER 。

INDEX

Page 25: Altibase管理培训 优化篇 v1.1

How Index Works (Index scan fail)

EMP_IDX1(INDEX)

EMP_IDX1(INDEX)

EMPLOYEE(TABLE)

EMPLOYEE(TABLE)

QueryProcessor

QueryProcessor

-UPPER(DNO) 将导致索引访问失效。查询将使用全表扫描 方式访问。-Altibase 不提供基于函数的索引 FBI(Function Based Index) ,所以在这种情况下,只能使用全表扫描。

Not Sorted Not Sorted

INDEX

Page 26: Altibase管理培训 优化篇 v1.1

INDEX SCAN Fail 的几种情况 • 对索引的列进行计算或者使用了函数。 Ex) SELECT * FROM T1 WHERE C1 +1 > 0

SELECT * FROM T1 WHERE TO_CHAR(SOME_DATE) = ‘2007-01-01’

• 索引列的类型不匹配 Ex) SELECT * FROM T1 WHERE CHAR_COLUMN = 1

Cf) CHAR 是 VARCHAR 类型的列。

• Altibase Optimizer 判断全表扫描的成本比索引扫描的成本更低的时候,将不使用索引。

• Composite Index 中没有使用索引的引导列。Ex) C1 + C2 是 Composite Index

SELECT * FROM T1 WHERE C2 = :value

Cf ) 把语句改成下面的方式,就可以使用 Composite Index

SELECT * FROM T1 WHERE C1 = :value1 and C2 = :value2

INDEX

Page 27: Altibase管理培训 优化篇 v1.1

INDEX SCAN Fail 的几种情况 ( 续 )

• NOT IN 子查询中的索引将失效 Ex) SELECT * FROM EMPLOYEE WHERE DNO NOT IN

(SELECT DNO FROM DEPARTMENT WHERE DNO > 4);

INDEX

Page 28: Altibase管理培训 优化篇 v1.1

即使 INDEX SCAN , Acess Count 依然很高• 使用 Cardinality 不好的 Index 时发生

-> 确认使用哪个 Index

-> A+B+C 形式的组合 Index 时,如果以 A, C 为条件,则 Access Count 有可能高 . (因为只使用 A 条件 )

INDEX

Page 29: Altibase管理培训 优化篇 v1.1

The Cases of Join optimization • JOIN CONDITION 中 FULL SCAN 或 Index Access Count 较高时,需要考虑创建 Index 或变更 Index 顺序• Index 使用效率不高或无法使用导致 FULL SCAN 时 • Altibase Optimizer 错误判断 JOIN Method 时 • 因过多表的 JOIN ,生成和验证执行计划的时间较长时• 该 GROUPING – JOIN 的语句以 JOIN – GROUPING 顺序做成时

Join Optimization

Page 30: Altibase管理培训 优化篇 v1.1

CASE1

在做表的 join 的时候,默认采用的是 NEST LOOP ,一般情况下,会把记录数少的结果集作为驱动表。-DEPARTMENT 的 DNO 列是 Primary Key , 所以首先会根据索引扫描 DEPARTMENT 表。- 再根据连接条件选择 EMPLOYEE 表的 DNO列上的索引 EMP_IDX 索引扫描 EMPLOYEE 表。

在做表的 join 的时候,默认采用的是 NEST LOOP ,一般情况下,会把记录数少的结果集作为驱动表。-DEPARTMENT 的 DNO 列是 Primary Key , 所以首先会根据索引扫描 DEPARTMENT 表。- 再根据连接条件选择 EMPLOYEE 表的 DNO列上的索引 EMP_IDX 索引扫描 EMPLOYEE 表。

Join Optimization

Page 31: Altibase管理培训 优化篇 v1.1

CASE2 (EMP_IDX INDEX 被删除 )

这个 CASE描述的是非正常情况下,我们需要把全表扫描的结果集作为驱动表,才能取得比较好的性能。- EMPLOYEE全表扫描,根据得到 DNO 再去 JOIN DEPARTMENT 表。 - 在 INDEX 被 DROP 的情况下,这是比较好的选择。如果这两个扫描的顺序反一下,执行计划将变得比较糟糕,因为增加了 EMPLOYEE 表全表扫描的次数。

这个 CASE描述的是非正常情况下,我们需要把全表扫描的结果集作为驱动表,才能取得比较好的性能。- EMPLOYEE全表扫描,根据得到 DNO 再去 JOIN DEPARTMENT 表。 - 在 INDEX 被 DROP 的情况下,这是比较好的选择。如果这两个扫描的顺序反一下,执行计划将变得比较糟糕,因为增加了 EMPLOYEE 表全表扫描的次数。

Join Optimization

Page 32: Altibase管理培训 优化篇 v1.1

Type mismatch in Join condition • 建议 Join Condition 里使用的数据类型保持一致• 内部进行型转换时,无法使用 INDEX

• 不得不使用的情况时确认 PLAN 并验证是否能使用 INDEX

Join Optimization

Page 33: Altibase管理培训 优化篇 v1.1

Specify your table only once if you possible. • Inline View , SubQuery 虽然提供 SQL 的易用性和便利性,但有一直访问同一张表的问题• 尽量只写一次表名,减少同一张表的重复访问• 优化成只访问一次表能获得结果集,如果不可行也要最少化访问

Join Optimization

Page 34: Altibase管理培训 优化篇 v1.1

Specify your table only once if you possible. • 尽量减少表的访问次数。例如下面这种情况 SELECT * FROM T1 WHERE (T1. i1 = 1 AND T1.i2 IN (SELECT a2 FROM T2 WHERE T2.a1 = T1.i1)) OR (T1. i1 = 2 AND T1.i2 IN (SELECT a2 FROM T2 WHERE T2.a1 = T1.i1));‘ 上面的语句应当改成: SELECT * FROM T1 WHERE T1. i1 IN (1, 2) AND T1.i2 IN (SELECT a2 FROM T2 WHERE T2.a1 = T1.i1));

Join Optimization

Page 35: Altibase管理培训 优化篇 v1.1

Reduce results before joining, if you possible. • 尽可能的缩小结果集,然后再进行 join

例如 : 例如 :

SELECT Y.DNO, Y.DNAME, SUM(SALARY) TOTAL_SALARYFROM EMPLOYEE X INNER JOIN DEPARTMENT Y ON X.DNO = Y.DNO GROUP BY Y.DNO, Y.DNAME

SELECT Y.DNO, Y.DNAME, SUM(SALARY) TOTAL_SALARYFROM EMPLOYEE X INNER JOIN DEPARTMENT Y ON X.DNO = Y.DNO GROUP BY Y.DNO, Y.DNAME

SELECT Y.DNO, Y.DNAME, X.TOTAL_SALARY FROM ( SELECT DNO, SUM(SALARY) TOTAL_SALARY FROM EMPLOYEE GROUP BY DNO ) X INNER JOIN DEPARTMENT Y ON X.DNO = Y.DNO

SELECT Y.DNO, Y.DNAME, X.TOTAL_SALARY FROM ( SELECT DNO, SUM(SALARY) TOTAL_SALARY FROM EMPLOYEE GROUP BY DNO ) X INNER JOIN DEPARTMENT Y ON X.DNO = Y.DNO

Join Optimization

Page 36: Altibase管理培训 优化篇 v1.1

Outer Join Optimization • Outer Join 时, Key Access Path 为基准表。

SELECT X.DNAME, Y.ENAME FROM DEPARTMENT X LEFT OUTER JOIN EMPLOYEE Y ON X.DNO = Y.DNO WHERE X.DNO = 1000 AND Y.ENO = 8890

SELECT X.DNAME, Y.ENAME FROM DEPARTMENT X LEFT OUTER JOIN EMPLOYEE Y ON X.DNO = Y.DNO WHERE X.DNO = 1000 AND Y.ENO = 8890

上面的示例中, X 表会作为基准表, X.DNO = 1000 会走索引。

Y 表则根据连接条件 X.DNO = Y.DNO 进行关联,不会使用 Y 表上的 Y.ENO=8890 上的索引。

上面的示例中, X 表会作为基准表, X.DNO = 1000 会走索引。

Y 表则根据连接条件 X.DNO = Y.DNO 进行关联,不会使用 Y 表上的 Y.ENO=8890 上的索引。

Join Optimization

Page 37: Altibase管理培训 优化篇 v1.1

Outer Join Optimization • 基准表没有索引时?

SELECT X.DNAME, Y.ENAME FROM DEPARTMENT X LEFT OUTER JOIN EMPLOYEE Y ON X.DNO = Y.DNO WHERE Y.ENO = 8890

SELECT X.DNAME, Y.ENAME FROM DEPARTMENT X LEFT OUTER JOIN EMPLOYEE Y ON X.DNO = Y.DNO WHERE Y.ENO = 8890

以上两个查询的结果是一致的。

对于 OUTER JOIN , Y.ENO 即使为 PK ,也无法使用索引。而对于 INNER JOIN ,则可以使用索引。

不必要的 OUTER JOIN 应当避免,可以使用 INNER JOIN来代替。

以上两个查询的结果是一致的。

对于 OUTER JOIN , Y.ENO 即使为 PK ,也无法使用索引。而对于 INNER JOIN ,则可以使用索引。

不必要的 OUTER JOIN 应当避免,可以使用 INNER JOIN来代替。

SELECT X.DNAME, Y.ENAME FROM DEPARTMENT X INNER JOIN EMPLOYEE Y ON X.DNO = Y.DNO WHERE Y.ENO = 8890

SELECT X.DNAME, Y.ENAME FROM DEPARTMENT X INNER JOIN EMPLOYEE Y ON X.DNO = Y.DNO WHERE Y.ENO = 8890

Join Optimization

Page 38: Altibase管理培训 优化篇 v1.1

Question

想在 EMPLOYEE 表中找到 SALARY 的前两名。 将 SALARY 排序取得前两名。想在 EMPLOYEE 表中找到 SALARY 的前两名。 将 SALARY 排序取得前两名。

SELECT ENAME, SALARY FROM EMPLOYEE ORDER BY SALARY DESC LIMIT 2

SELECT ENAME, SALARY FROM EMPLOYEE ORDER BY SALARY DESC LIMIT 2

结果是对的,但是如果这个语句执行的频率非常高呢 ?

Limit Optimization

Page 39: Altibase管理培训 优化篇 v1.1

Question Result

- 对 EMPLOYEE 表进行全表扫描并排序,取得前两行。如果这张表有 1 亿行记录呢?那这个代价将是非常昂贵的。- 对 EMPLOYEE 表进行全表扫描并排序,取得前两行。如果这张表有 1 亿行记录呢?那这个代价将是非常昂贵的。

Limit Optimization

Page 40: Altibase管理培训 优化篇 v1.1

Solution

- 同样的结果,但执行效率非常高,并且受表的记录数大小影响很小。- 同样的结果,但执行效率非常高,并且受表的记录数大小影响很小。

Limit Optimization

Page 41: Altibase管理培训 优化篇 v1.1

Why ?

Idx_emp_salary(INDEX)

Idx_emp_salary(INDEX)

EMPLOYEE(TABLE)

EMPLOYEE(TABLE)

QueryProcessor

QueryProcessor

STOP

- 通过索引访问表两次。 - SALARY 上的索引是 DESC 创建的 , 带了 where salary>0 ,所以可以使用索引访问。- Limit 2 返回的记录即为 salary 最大的两条记录。- 由于直接通过索引访问,表即便再大,对查询的效率影响也不大。

- 通过索引访问表两次。 - SALARY 上的索引是 DESC 创建的 , 带了 where salary>0 ,所以可以使用索引访问。- Limit 2 返回的记录即为 salary 最大的两条记录。- 由于直接通过索引访问,表即便再大,对查询的效率影响也不大。

Limit Optimization

Page 42: Altibase管理培训 优化篇 v1.1

Limit Stop key 使用说明 • 一般的情况下,我们使用 limit 的目的是为了减少表的访问量。• 下面的几种情况下 limit将无法有效发挥作用:1 、 GROUP BY 将使 limit

2 、无法使用索引的 order by 操作3 、带很多的 where条件

Limit Optimization

Page 43: Altibase管理培训 优化篇 v1.1

The Cases of Subquery Optimization • 因使用过多的 Subquery ,频繁访问同一张表时• 因对 NOT IN 的理解不够,对于大的结果集使用 NOT IN 时• Subquery 条件里没有 INDEX 字段时

SUB-QUERY

Page 44: Altibase管理培训 优化篇 v1.1

If you read your table twice or more … • Subquery 是嵌入到另一个 SQL 语句中的 SELECT 语句,频繁读取同一张表时影响性能 • 内查询的结果集被用作外查询的搜索值,所以内查询的结果集越大性能下降越严重 (注意 !!)

• 如果 SubQuery 的结果集里只取一条记录,建议在 SubQuery 里使用 LIMIT 1

• 如果同一张表被查询两次以上,尽量把 SubQuery 转换为 JOIN

• 所有的 SubQuery 都可以转换为 Join 形态

SUB-QUERY

Page 45: Altibase管理培训 优化篇 v1.1

SubQuery -> Joining form• 使用表连接取代子查询。一般情况下,表连接的效率高于子查询。

SELECT X.ENAME, (SELECT DNAME FROM DEPARTMENT WHERE DNO = X.DNO) DNAME, (SELECT DTEL FROM DEPARTMENT WHERE DNO = X.DNO) DTEL , (SELECT DLOCATION FROM DEPARTMENT WHERE DNO = X.DNO) DLOCATIONFROM EMPLOYEE X;

SELECT X.ENAME, (SELECT DNAME FROM DEPARTMENT WHERE DNO = X.DNO) DNAME, (SELECT DTEL FROM DEPARTMENT WHERE DNO = X.DNO) DTEL , (SELECT DLOCATION FROM DEPARTMENT WHERE DNO = X.DNO) DLOCATIONFROM EMPLOYEE X;

SELECT X.ENAME, Y.DNAME, Y.DTEL , Y.DLOCATIONFROM EMPLOYEE X INNER JOIN DEPARTMENT Y ON X.DNO = Y.DNO;

SELECT X.ENAME, Y.DNAME, Y.DTEL , Y.DLOCATIONFROM EMPLOYEE X INNER JOIN DEPARTMENT Y ON X.DNO = Y.DNO;

SUB-QUERY

Page 46: Altibase管理培训 优化篇 v1.1

Avoiding NOT IN Sub Query … • NOT IN 无法使用索引。 • 使用 JOIN取代 NOT IN 。

SELECT * FROM EMPLOYEE WHERE DNO NOT IN (SELECT DNO FROM DEPARTMENT_DELETED); SELECT * FROM EMPLOYEE WHERE DNO NOT IN (SELECT DNO FROM DEPARTMENT_DELETED);

SELECT X.*FROM EMPLOYEE X LEFT OUTER JOIN DEPARTMENT_DELETED Y ON X.DNO = Y.DNO WHERE Y.DNO IS NULL

SELECT X.*FROM EMPLOYEE X LEFT OUTER JOIN DEPARTMENT_DELETED Y ON X.DNO = Y.DNO WHERE Y.DNO IS NULL

SUB-QUERY

Page 47: Altibase管理培训 优化篇 v1.1

V$STATEMENT • 我们可以通过性能视图 v$statement来查看 SQL语句的执行情况。例如我们可以通过下面的语句来找出执行时间比较长的语句• 较长的 Query 时, SQL语句显示不全• 显示查询时执行的 SQL语句

SELECT SESSION_ID, EXECUTE_SUCCESS, EXECUTE_TIME/1000 || ‘ms’ EXEC_MSEC, FETCH_TIME/1000 || ‘ms’ FETCH_MSEC, RPAD(SUBSTR(QUERY,1,80), 80, ‘ ‘) QRYFROM V$STATEMENT ORDER BY EXECUTE_TIME DESC, EXECUTE_SUCCESS DESC;

SELECT SESSION_ID, EXECUTE_SUCCESS, EXECUTE_TIME/1000 || ‘ms’ EXEC_MSEC, FETCH_TIME/1000 || ‘ms’ FETCH_MSEC, RPAD(SUBSTR(QUERY,1,80), 80, ‘ ‘) QRYFROM V$STATEMENT ORDER BY EXECUTE_TIME DESC, EXECUTE_SUCCESS DESC;

Collecting Queries

Page 48: Altibase管理培训 优化篇 v1.1

INSERT / UPDATE /DELETE• INSERT 执行慢可能的情况 -> Too Many Indices ?

-> 存在 Table Lock ( 可查询 V$LOCK视图 )

-> I/O Contention ?

• UPDATE / DELETE 执行慢可能情况 -> 所有导致 SELECT 执行慢的情况 -> 所有导致 INSERT 执行慢的情况 -> 不必要的 Key 字段 Update

DML Optimization

Page 49: Altibase管理培训 优化篇 v1.1

Contact Point

天津南大通用数据技术有限公司天津总部 :天津华苑产业园区海泰发展六道 6 号邮 编: 300384 电 话: 022-58815881传   真: 022-58815882北京业务中心:北京海淀区金源时代商务中心 2 号楼 A 座 17D邮 编: 100089 电 话: 010-88866866 传   真: 010-88864556Web : http://www.generaldata.com.cn

谢谢