热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

一次IO利用率100%,数据库大量全表扫描问题

一次IO利用率100%,数据库大量全表扫描问题现象描述1,具体什么业务受到影响不清楚,但从系统测看,主机IO资源比较紧张(HPUX11.31+oracle9i)HP-UXcrmdb3B.11.23Uia6409/19/12www.2cto.c...SyntaxHighlighte

一次IO利用率100%,数据库大量全表扫描问题
 
现象描述
 1, 具体什么业务受到影响不清楚,但从系统测看,主机IO资源比较紧张(HPUX 11.31 +oracle 9i)
HP-UX crmdb3 B.11.23 U ia64    09/19/12
  www.2cto.com  
11:09:42    %usr    %sys    %wio   %idle
11:09:45      28       5      64       3
11:09:48      28       2      61       9
11:09:51      28       2      67       3
11:09:54      33       2      57       7
11:09:57      31       2      59       7
 
glance看IO已接近100%
 
2,数据库侧看,大量db file scattered read IO相关等待事件
 
[sql] 
 SID    SERIAL# OSUSER   USERNAME SVRPROC                              SQL_HASH_VALUE EVENT                                             P1         P2         P3  
------ ---------- -------- -------- ------------------------------------ -------------- ------------------------------ --------------------- ---------- ----------  
    89      28200 airsm    ai    10261                                     664153718 db file scattered read                            37     192750          8  
   159      43064 airsm    ai    26996                                    3295997871 db file scattered read                            36      60587          8  
   173       8048 airsm    ai    3250                                     1002585284 db file scattered read                            36      75123          8  
   458      18261 airsm    ai    2505                                     2812298138 db file scattered read                            36     365179          8  
……..  
  
3,等待的sql具体如下,主要原因是对ai.RM_A_x全表扫描,该表72GB大小。
 
[sql] 
SQL> @get_sql_by_hv  
Enter value for hv: 1775869170  
old   3:  where hash_value = '&HV'  
new   3:  where hash_value = '1775869170'  
  
SQL Text    www.2cto.com  
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  
select a.serial_num, x.c_attr_1 crypto, to_char(a.expirt_dt, 'yy  
yy-mm-dd') expirt_dt, k.key_info     from RM_A_x x, RM_A  
 a, RM_A_key_info k  
 where a.row_id = x.row_id (+)  
                                   and k.row_id(+) = x.n_attr_1  
                                                               a  
nd serial_num in (  '12475014246302465', '12475014246302485', '1  
2475014246302572', '12475014246302595', '12475014246302599', '12  
475014246302620', '12475014246302636', '12475014246302765')  
  
9 rows selected.  
  
SQL> /  
Enter value for hv: 2144161010  
old   3:  where hash_value = '&HV'  
new   3:  where hash_value = '2144161010'  
www.2cto.com  
SQL Text  
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  
select a.serial_num, x.c_attr_1 crypto, to_char(a.expirt_dt, 'yy  
yy-mm-dd') expirt_dt, k.key_info     from RM_A_x x, RM_A  
 a, RM_A_key_info k  
 where a.row_id = x.row_id (+)  
                                   and k.row_id(+) = x.n_attr_1  
                                                               a  
nd serial_num in (  '12475014246306603', '12475014246306726', '1  
2475014246306804')  
  
8 rows selected.  
  
SQL>  select bytes/1024/1024 M,owner from dba_segments where segment_name ='RM_A';  
  
         M OWNER  
---------- ------------------------------------------------------------------------------------------  
     71206 ai  
       
SQL> @showplan_9i  
Enter value for hash: 125827763  
old  29: hash_value='&hash'  
new  29: hash_value='125827763'  
    www.2cto.com  
Optimizer Plan:  
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  
| Operation | PHV/Object Name | Rows | Bytes| Cost |  
|SELECT STATEMENT                |----- 125827763 [0]  
-|       |      |        |  
  
|NESTED LOOPS OUTER              |                     |       |      |        |  
| NESTED LOOPS OUTER             |                     |       |      |        |  
|  TABLE ACCESS FULL             |RM_A             |       |      |        |  
|  TABLE ACCESS BY INDEX ROWID   |RM_A_X           |       |      |        |  
|   INDEX UNIQUE SCAN            |RM_A_X_P1        |       |      |        |  
| TABLE ACCESS BY INDEX ROWID    |RM_A_KEY_INFO    |       |      |        |  
|  INDEX UNIQUE SCAN             |RM_A_KEY_INFO_P1 |       |      |        |  
  www.2cto.com  
原因分析
 
1,该表有相关索引,RM_A_M1对应SERIAL_NUM列的索引,字段类型也匹配
 
[sql] 
Index           Column                     Col Column  
Name            Name                       Pos Details  
--------------- ------------------------- ---- ------------------------  
RM_A_F1     BUCKET_ID                    1 NUMBER(15,0)  
                BUCKET_ID                    1 NUMBER(15,0)  
RM_A_F2     INV_ID                       1 NUMBER(15,0)  
                INV_ID                       1 NUMBER(15,0)  
RM_A_M1     SERIAL_NUM                   1 VARCHAR2(80)  
                SERIAL_NUM                   1 VARCHAR2(80)  
  www.2cto.com  
2,为什么不走索引呢.原来是使用基于rule类型的优化器,RULE优化器根据FROM列表中的位置来选择驱动表,FROM列表中最后一个表被作为驱动表。
 
[sql] 
SQL>  select OPTIMIZER_MODE from  v$sqlarea where HASH_VALUE='125827763';  
  
OPTIMIZER_MODE  
---------------------------------------------------------------------------  
RULE  
  
Table                   Number                 Empty Average    Chain Average Global User           Sample Date  
Name                   of Rows   Blocks       Blocks   Space    Count Row Len Stats  Stats            Size MM-DD-YYYY  
--------------- -------------- -------- ------------ ------- -------- ------- ------ ------ -------------- ----------  
RM_A_X                                                                    NO     NO  
  
SQL>  select CREATED,OBJECT_NAME from  dba_objects where object_name ='RM_A_X' and owner='ai';  
    www.2cto.com  
CREATED                                                                                              OBJECT_NAME  
---------------------------------------------------------------------------------------------------- --------------------  
2012-06-26 09:52:48                                                                                  RM_A_X  
  
SQL> show parameter optimizer_mode  
  
NAME                                 TYPE                              VALUE  
------------------------------------ --------------------------------- ------------------------------  
optimizer_mode                       string                            RULE  
3,rbo的执行顺序如下,安装如下文章所述,IN应该属于rank 10,如果把in改成单条件=则直接走相关索引
  www.2cto.com  
sing the RBO, the optimizer chooses an execution plan based on the access paths available and the ranks of these access paths. Oracle's ranking of the access paths is heuristic. If there is more than one way to execute a SQL statement, then the RBO always uses the operation with the lower rank. Usually, operations of lower rank execute faster than those associated with constructs of higher rank.
The list shows access paths and their ranking:
 
RBO Path 1: Single Row by Rowid
RBO Path 2: Single Row by Cluster Join
RBO Path 3: Single Row by Hash Cluster Key with Unique or Primary Key
RBO Path 4: Single Row by Unique or Primary Key
RBO Path 5: Clustered Join
RBO Path 6: Hash Cluster Key
RBO Path 7: Indexed Cluster Key
RBO Path 8: Composite Index
RBO Path 9: Single-Column Indexes
RBO Path 10: Bounded Range Search on Indexed Columns
RBO Path 11: Unbounded Range Search on Indexed Columns
RBO Path 12: Sort Merge Join
RBO Path 13: MAX or MIN of Indexed Column
RBO Path 14: ORDER BY on Indexed Column
RBO Path 15: Full Table Scan
 
解决方案:
  www.2cto.com  
  由于问题比较紧急,需要尽快解决,因此使用了最简单有效的解决办法用hint,使用此方法修改sql后问题很快解决。
  SQL> explain plan for
  2  select /*+index(a RM_A_M1) */ a.serial_num, x.c_attr_1 crypto, to_char(a.expirt_dt, 'yyyy-mm-dd') expirt_dt, k.key_info     from  ai.RM_A_key_info k ,ai.RM_A_x x ,ai.RM_A 
  3   a where a.row_id = x.row_id (+)
  4  and k.row_id(+) = x.n_attr_1        and serial_num in (  '12475014246300079', '12475014246300099');
 
Explained.
 
SQL>  select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  www.2cto.com  
----------------------------------------------------------------------------------------
| Id  | Operation                      |  Name                 | Rows  | Bytes | Cost  |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                       |     2 |  6204 |     9 |
|   1 |  NESTED LOOPS OUTER            |                       |     2 |  6204 |     9 |
|   2 |   NESTED LOOPS OUTER           |                       |     2 |  4126 |     7 |
|   3 |    INLIST ITERATOR             |                       |       |       |       |
|   4 |     TABLE ACCESS BY INDEX ROWID| RM_A              |     2 |    70 |     5 |
|*  5 |      INDEX RANGE SCAN          | RM_A_M1           |     2 |       |     4 |
|   6 |    TABLE ACCESS BY INDEX ROWID | RM_A_X            |     1 |  2028 |     1 |
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|*  7 |     INDEX UNIQUE SCAN          | RM_A_X_P1         |     1 |       |       |
|   8 |   TABLE ACCESS BY INDEX ROWID  | RM_A_KEY_INFO     |     1 |  1039 |     1 |
|*  9 |    INDEX UNIQUE SCAN           | RM_A_KEY_INFO_P1  |     1 |       |       |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
 
   5 - access("A"."SERIAL_NUM"='12475014246300079' OR
              "A"."SERIAL_NUM"='12475014246300099')
   7 - access("A"."ROW_ID"="X"."ROW_ID"(+))
  www.2cto.com  
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
   9 - access("K"."ROW_ID"(+)="X"."N_ATTR_1")
 
Note: cpu costing is off
 
25 rows selected.
 
参考资料
 
http://docs.oracle.com/cd/B10501_01/server.920/a96533/rbo.htm#39232

推荐阅读
  • Netflix利用Druid实现高效实时数据分析
    本文探讨了全球领先的在线娱乐公司Netflix如何通过采用Apache Druid,实现了高效的数据采集、处理和实时分析,从而显著提升了用户体验和业务决策的准确性。文章详细介绍了Netflix在系统架构、数据摄取、管理和查询方面的实践,并展示了Druid在大规模数据处理中的卓越性能。 ... [详细]
  • 本文介绍了一个SQL Server自定义函数,用于从字符串中提取仅包含数字和小数点的子串。该函数通过循环删除非数字字符来实现,并附带创建测试表、存储过程以演示其应用。 ... [详细]
  • JavaScript 中创建对象的多种方法
    本文详细介绍了 JavaScript 中创建对象的几种常见方式,包括对象字面量、构造函数和 Object.create 方法,并提供了示例代码和属性描述符的解释。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 本文介绍如何使用SAS根据输入数据集自动生成并执行SQL查询,其中CASE语句依据另一个数据集中的观测值动态调整。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • Oracle中NULL、空字符串和空格的处理与区别
    本文探讨了在Oracle数据库中使用NULL、空字符串('')和空格('_')时可能遇到的问题及解决方案。重点解释了它们之间的区别,以及在查询和函数中的行为。 ... [详细]
  • Oracle 数据导出为 SQL 脚本的详细步骤
    本文介绍如何使用 PL/SQL Developer 工具将 Oracle 数据库中的数据导出为 SQL 脚本,包括详细的步骤和注意事项。 ... [详细]
  • 简化报表生成:EasyReport工具的全面解析
    本文详细介绍了EasyReport,一个易于使用的开源Web报表工具。该工具支持Hadoop、HBase及多种关系型数据库,能够将SQL查询结果转换为HTML表格,并提供Excel导出、图表显示和表头冻结等功能。 ... [详细]
  • 1.介绍有时候我们需要一些模拟数据来进行测试,今天简单记录下如何用存储过程生成一些随机数据。2.建表我们新建一张学生表和教师表如下:CREATETABLEstudent(idINT ... [详细]
  • 1.执行sqlsever存储过程,消息:SQLServer阻止了对组件“AdHocDistributedQueries”的STATEMENT“OpenRowsetOpenDatas ... [详细]
  • 在Fedora 31上部署PostgreSQL 12
    本文详细介绍如何在Fedora 31操作系统上安装和配置PostgreSQL 12数据库。包括环境准备、安装步骤、配置优化以及安全设置,确保数据库能够稳定运行并提供高效的性能。 ... [详细]
  • 本文介绍了解决在Windows操作系统或SQL Server Management Studio (SSMS) 中遇到的“microsoft.ACE.oledb.12.0”提供程序未注册问题的方法,特别针对Access Database Engine组件的安装。 ... [详细]
  • PostgreSQL 最新动态 —— 2022年4月6日
    了解 PostgreSQL 社区的最新进展和技术分享 ... [详细]
  • 本文详细介绍了MySQL数据库中的Bin Log和Redo Log,阐述了它们在日志记录机制、应用场景以及数据恢复方面的区别。通过对比分析,帮助读者更好地理解这两种日志文件的作用和特性。 ... [详细]
author-avatar
王立君淑霖_189
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有