最近遇到一个语句, 只要一执行这个语句就会出现报错临时表空间不足,回想一下在语句中用到临时表空间无非是大量的SORT和HASH,然后通过执行计划查看如下:
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3959216560
-------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | OMem | 1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------
| 1 | HASH UNIQUE | | 1 | 4 | 0 |00:00:00.01 | | | |
| 2 | NESTED LOOPS OUTER | | 1 | 4 | 0 |00:00:00.01 | | | |
|* 3 | HASH JOIN | | 1 | 4 | 0 |00:00:00.01 | 703K| 703K| |
| 4 | NESTED LOOPS OUTER | | 1 | 4 | 2524K|00:02:17.15 | | | |
| 5 | NESTED LOOPS | | 1 | 4 | 2524K|00:01:34.23 | | | |
|* 6 | HASH JOIN | | 1 | 4 | 2524K|00:00:53.84 | 2047M| 29M| 55M (1)|
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|* 7 | HASH JOIN | | 1 | 4 | 11M|00:01:00.03 | 2797K| 1148K| 3144K (0)|
|* 8 | TABLE ACCESS BY INDEX ROWID | T_COMMISSION_FEE | 1 | 25517 | 31948 |00:00:00.16 | | | |
|* 9 | INDEX RANGE SCAN | PK_T_COMMISSION_FEE | 1 | 25520 | 31948 |00:00:00.03 | | | |
|* 10 | HASH JOIN | | 1 | 33714 | 11M|00:00:12.24 | 1299K| 1299K| 1925K (0)|
|* 11 | TABLE ACCESS FULL | T_GL_BIZ_INTERFACE | 1 | 7889 | 12414 |00:00:00.10 | | | |
|* 12 | TABLE ACCESS FULL | T_BIZ_ACCOUNTING_INFO | 1 | 32696 | 63896 |00:00:00.27 | | | |
| 13 | VIEW | VW_NSO_1 | 1 | 3 | 2 |00:00:00.01 | | | |
|* 14 | FILTER | | 1 | | 2 |00:00:00.01 | | | |
|* 15 | CONNECT BY WITH FILTERING | | 1 | | 2 |00:00:00.01 | 9216 | 9216 | 8192 (0)|
| 16 | TABLE ACCESS BY INDEX ROWID| test| 1 | | 1 |00:00:00.01 | | | |
|* 17 | INDEX FULL SCAN | tes123| 1 | 1 | 1 |00:00:00.01 | | | |
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 18 | NESTED LOOPS | | 2 | | 1 |00:00:00.01 | | | |
| 19 | BUFFER SORT | | 2 | | 2 |00:00:00.01 | 9216 | 9216 | 8192 (0)|
| 20 | CONNECT BY PUMP | | 2 | | 2 |00:00:00.01 | | | |
|* 21 | INDEX RANGE SCAN | Ttest123| 2 | 3 | 1 |00:00:00.01 | | | |
| 22 | TABLE ACCESS FULL | test| 0 | 3 | 0 |00:00:00.01 | | | |
| 23 | TABLE ACCESS BY INDEX ROWID | test| 2524K| 1 | 2524K|00:00:30.72 | | | |
|* 24 | INDEX UNIQUE SCAN | test123| 2524K| 1 | 2524K|00:00:12.32 | | | |
| 25 | TABLE ACCESS BY INDEX ROWID | Ttt| 2524K| 1 | 2524K|00:00:31.35 | | | |
|* 26 | INDEX UNIQUE SCAN | tet1| 2524K| 1 | 2524K|00:00:12.00 | | | |
| 27 | TABLE ACCESS FULL | test31| 0 | 84 | 0 |00:00:00.01 | | | |
| 28 | TABLE ACCESS BY INDEX ROWID | tes1234| 0 | 1 | 0 |00:00:00.01 | | | |
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|* 29 | INDEX UNIQUE SCAN | PK_T_CONTRACT_MASTER | 0 | 1 | 0 |00:00:00.01 | | | |
-------------------------------------------------------------------------------------------------------------------------------------------
第6步太吓人了,我这个语句没有运行完因为会报错,这个状态应该是在故障点的,可以看到需要的HASH构造区域为2G,仔细分析下这个执行计划。
其实它是一个HASH JION和一个VIEW做的HASH JION,观察一下行数,就是11M(11*1024*1024)行和2行进行的一个HANSH JION,但是很奇怪的是执行
计划选择了大数据集为构造输入,构造输入在PGA的工作区的HASH_AREA_SIZE中建立一个HASH表,如果内存不够把HASH表存储在TMEP表空间里面,
而选择了小的数据集来作为探测输入,探测输入会通过连接条件通过HASH函数和HASH表进行比对,如果存在则输出,不存在则丢弃。下面我们通过
一个小小的试验来说明:
建立表
SQL> desc test;
Name Type Nullable Default Comments
----- ------------ -------- ------- --------
员工代码 NUMBER(20) Y
员工中文名 VARCHAR2(50) Y
员工英文名 VARCHAR2(50) Y
归属机构 VARCHAR2(50) Y
岗位名称 VARCHAR2(50) Y
SQL> select count(*) from test;
COUNT(*)
----------
3399680
这个是大数据集
建立表
SQL> desc test2
Name Type Nullable Default Comments
---- ---------- -------- ------- --------
员工代码 NUMBER(20) Y
工资 NUMBER(10) Y
SQL> select count(*) from test2;
COUNT(*)
----------
3
现在试验开始
首先执行语句
SQL> select count(*) from test a,test2 b where a.员工代码=b.员工代码;
COUNT(*)
----------
15360
已用时间: 00: 00: 09.12
执行计划
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=ALL_ROWS (Cost=6098 Card=1 Bytes=
14)
1 0 SORT (AGGREGATE)
2 1 HASH JOIN (Cost=6098 Card=13197 Bytes=184758)
3 2 TABLE ACCESS (FULL) OF 'TEST2' (TABLE) (Cost=3 Card=3
Bytes=21)
4 2 TABLE ACCESS (FULL) OF 'TEST' (TABLE) (Cost=6063 Card=
3409202 Bytes=23864414)
可以看到这个时候小数据集作TEST2为了构造输入,在执行期间通过语句
select operation_id,operation_type,actual_mem_used,tempseg_size,tablespace
from v$session s,v$sql_workarea_active w
where s.sid=w.sid
and S.SID=151;
得出的结果如下:
OPERATION_ID OPERATION_TYPE ACTUAL_MEM_USED TEMPSEG_SIZE TABLESPACE
------------ ---------------------------------------- --------------- ------------ -------------------------------
2 HASH-JOIN 183296
HASH JION用于构造HASH表使用内存183K没有使用临时表空间。
现在我们通过HINT来改变大数据集和小数据集的顺序,执行语句如下:
SQL> select /*+ leading(a) use_hash(a b) */ count(*) from test a,test2 b where a.员工代码=b.员工代码;
COUNT(*)
----------
15360
已用时间: 00: 00: 13.82
执行计划
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=ALL_ROWS (Cost=10636 Card=1 Bytes
=14)
1 0 SORT (AGGREGATE)
2 1 HASH JOIN (Cost=10636 Card=13197 Bytes=184758)
3 2 TABLE ACCESS (FULL) OF 'TEST' (TABLE) (Cost=6063 Card=
3409202 Bytes=23864414)
4 2 TABLE ACCESS (FULL) OF 'TEST2' (TABLE) (Cost=3 Card=3
Bytes=21)
这个时候TEST大数据集是构造输入,同样在执行期间通过语句得出结果
OPERATION_ID OPERATION_TYPE ACTUAL_MEM_USED TEMPSEG_SIZE TABLESPACE
------------ ---------------------------------------- --------------- ------------ -------------------------------
2 HASH-JOIN 1205248 18874368 TEMP
可以看到结果不同了,使用1.2M内存,使用临时表空间近19M。
同时如果我们关注下以下信息:
SQL> select * from v$sysstat where NAME LIKE '%workarea executions%';
STATISTIC# NAME CLASS VALUE STAT_ID
---------- ---------------------------------------------------------------- ---------- ---------- ----------
294 workarea executions - optimal 64 3525 3211650785
295 workarea executions - onepass 64 4 798730793
296 workarea executions - multipass 64 0 3804491469
现在我们运行
SQL> select /*+ leading(a) use_hash(a b) */ count(*) from test a,test2 b where a.员工代码=b.员工代码;
COUNT(*)
----------
15360
在运行
SQL> select * from v$sysstat where NAME LIKE '%workarea executions%';
STATISTIC# NAME CLASS VALUE STAT_ID
---------- ---------------------------------------------------------------- ---------- ---------- ----------
294 workarea executions - optimal 64 3525 3211650785
295 workarea executions - onepass 64 5 798730793
296 workarea executions - multipass 64 0 3804491469
可以看到workarea executions - onepass 增加了1说明我们进行了一次物理交换才完成了探测(还好没有多次)。
有了上面的试验,我的语句应该就可以通过HINT来改变小数据集为构造输入,而大数据集为探测输入来改变临时表空间不足的问题,同时提高性能。
- 一次HASH_JOIN_临时表空间不足的分析和优化思路.rar (2.8 KB)
- 下载次数: 5
发表评论
-
查看当前Session SQL
2014-07-08 11:51 1092SELECT (SELECT listagg(b.sql_te ... -
CLOB列 XML信息查看
2014-05-28 10:28 1028--使用该SQL查询节点情况 SELECT * FROM ... -
【转】ORACLE 临时表空间使用率过高的原因及解决方案
2012-12-25 15:24 1025http://www.cnblogs.com/wonder31 ... -
oracle:获取session的IP地址
2012-10-20 02:38 4311方法1 创建触发器: create orreplace ... -
Oracle ora-01002
2012-08-11 02:43 28958ORA-01002:fetch超出序列 ... -
提高Oracle SQL的执行效率的3个方案
2012-08-08 00:57 1006如果你想要提高Oracle SQL ... -
Oracle STA
2012-08-06 11:32 0第一步:创建优化任务 ... -
Oracle SQL小技巧
2012-08-06 11:21 01.两个字段可空的判断相等,用decode判断。 例子:d ... -
自动工作负载库(Automatic Workload Repository,AWR)
2012-07-23 22:45 1433自动工作负载库(Automatic Workload Repo ... -
orace的隔离级别
2012-07-21 01:06 1107隔离级别(isoation eve) 隔离级别定义了事务与 ... -
Oracle SQLID 与 Hash_value 之间的相互转化
2012-07-20 00:55 4720一、什么是SQLID SQLID是根据SQL 文本,经过 ... -
Oracle优化器和索引原
2012-07-13 00:34 1286Oracle优化器和索引原理 ============ ... -
Oracle优化器的RBO和CBO方式
2012-07-13 00:25 2405[/size]Or[size=large][size=smal ... -
Oracle 优化器详解
2012-07-13 00:18 1357一、优化器基本知识 Oracle在执行一个SQL之前,首先 ... -
SQL中使用WITH AS提高性能
2012-07-05 23:30 1262摘要:本文结合笔者实 ... -
Ibatis调用Oracle存储过程,以及返回Cursor结果集的问题
2012-07-01 23:46 2139最近开始接触Oracle了,接触的越多越感受到自己的渺小!(o ... -
Oracle表连接操作——Hash Join(哈希连接
2012-05-20 17:05 0连接 http://space.itpub.net/?uid ... -
Oracle hash join
2012-05-20 17:00 959hash join是oracle里面一个 ... -
SQL*PLUS SET 变量
2012-05-02 22:46 882SQL*PLUS SET变量 SQL*PLUS维护系 ... -
转---借助内存表处理复杂的oracle查询要求.
2012-03-25 23:23 1423借助内存表处理复杂的oracle查询要求. 在日常业务处理过 ...
相关推荐
6. Hash Join 的作用:Hash Join 可以提高 SQL 语句的执行效率,但其也可能会消耗大量的临时表空间。 7. Oracle 数据库的性能优化:Oracle 数据库的性能优化需要从多方面入手,包括服务器硬件性能、操作系统设置、...
需要注意的是,临时表空间的优化是一个持续的过程,需要根据实际业务需求和系统负载进行调整。希望本文能够帮助读者更好地理解和运用 MySQL 的临时表空间,从而提升数据库的处理能力和用户体验。
在本文中,我们将深入探讨通过分析SQL语句的执行计划来优化JOIN的方法,特别是关注JOIN过程中的顺序和连接类型。 JOIN过程通常涉及两个row source(表),并且在大多数情况下,JOIN操作的步骤是串行的。尽管可以...
如果内存不足,则可能需要使用临时表空间,进一步降低性能。 - 第一次返回结果的速度相对较慢,尤其是当需要从磁盘读取数据时。 ### 总结 每种连接方式都有其特定的应用场景: - **嵌套循环连接**适用于查询条件...
例如,如果有一个学生表和课程表,学生表中的"course_id"可以作为外键,引用课程表的"course_id"主键,这样就能确保每个学生只能选择存在的课程。 接着,表连接(Table Join)是多表查询的常用方法。常见的连接类型...
- 如果表很大无法完全放入内存,优化器会将其分割成多个分区,并使用临时段进行I/O操作,此时需确保有足够的临时空间。 #### SORT MERGE JOIN SORT MERGE JOIN是一种基于排序的连接方法,通常包括三个步骤:对每个...
4. 创造并监测临时表空间:合理分配和管理临时表空间,避免空间不足导致的排序问题。 了解在内存中执行排序的数量有助于优化资源分配,通过监控 PGA 的使用情况,可以发现排序操作对内存的需求,进而调整相关参数。...
11.3.2 一次Hash Join 的 优化全过程 320 11.3.3 一次 Merge Sort Join 的优化全过程 324 11.3.4 一次统计信息收集不准确引发的NL性能瓶颈 329 11.4 本章习题、总结与延伸 332 第12章 动手,经典等价改写让SQL...
11.3.2 一次Hash Join 的 优化全过程 320 11.3.3 一次 Merge Sort Join 的优化全过程 324 11.3.4 一次统计信息收集不准确引发的NL性能瓶颈 329 11.4 本章习题、总结与延伸 332 第12章 动手,经典等价改写让SQL...
- HASH JOIN:适用于大数据量的连接,当内存足够时,可以一次性加载所有数据进行比较。 - NESTED LOOP JOIN:对于小表驱动大表的情况,NLJ可以有效利用索引,但不适合大数据量。 - SORT MERGE JOIN:需要对参与JOIN...
- **避免子查询**:考虑使用JOIN替代子查询,或通过临时表优化。 5. **存储引擎优化** - **InnoDB与MyISAM比较**:InnoDB支持事务和行级锁定,适合大量并发写操作;MyISAM则适用于读多写少的场景。 - **存储格式...
这包括选择合适的索引策略、确定最佳的排序和分组方法、决定何时使用临时表等。物理优化通常基于成本模型,评估不同操作的成本,选择最低成本的执行计划。数据库管理系统会考虑各种因素,如I/O成本、CPU开销、内存...
优化器扫描小表(或数据源),利用连接键(也就是根据连接字段计算hash值)在内存中建立hash表,然后扫描大表,每读到一条记录就来探测hash表一次,找出与hash表匹配的行。当小表可以全部放入内存中,其成本接近全表...
8. **定期分析和优化表**:ANALYZE TABLE和OPTIMIZE TABLE命令可以帮助更新统计信息,优化存储空间。 9. **适当设置缓存和缓冲池**:增大innodb_buffer_pool_size以缓存数据和索引,减少磁盘I/O。 10. **避免...
当排序所需空间超过`sort_area_size`参数设定的大小时,Oracle会在临时表空间进行磁盘排序,这比内存排序慢得多。 2. **合理设置参数**:通过调整`sort_area_size`等参数来优化排序过程,减少磁盘排序的发生。 3. **...
6. JOIN 优化:避免笛卡尔积,合理使用 INNER JOIN 和 OUTER JOIN,减少临时表的使用。 7. 表设计优化:采用正常化设计,减少冗余数据;考虑数据类型的选择,减少存储空间。 8. 使用慢查询日志:监控慢查询,找出...