`

oracle 聚簇因子(Cluster Factor)

阅读更多
文章来源:http://www.itpub.net/thread-1317424-1-1.html#


select table_name,index_name from user_indexes where table_name='TORDER'  //查看索引
select * from user_ind_columns where index_name=upper('&index_name');

select index_name,monitoring,used,start_monitoring,end_monitoring from v$object_usage




一次简单的性能优化诊断,聚簇因子过高导致全表扫描。


业务人员反映一个查询非常慢:
--------------------------------------------------------------------------------
select * from ab44 where aae002=201006;
--------------------------------------------------------------------------------
查看索引的句子




查看执行计划,是全表扫描
SQL> explain plan for select * from ab44 where aae002=201006;
已解释。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
Plan hash value: 781340439                                                      
                                                                                
--------------------------------------------------------------------------      
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |      
--------------------------------------------------------------------------      
|   0 | SELECT STATEMENT  |      | 10554 |   865K|  8777   (3)| 00:01:46 |      
|*  1 |  TABLE ACCESS FULL| AB44 | 10554 |   865K|  8777   (3)| 00:01:46 |      
--------------------------------------------------------------------------      
                                                                                
Predicate Information (identified by operation id):                             
---------------------------------------------------                             
PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
                                                                                
   1 - filter("AAE002"=201006)                                                  
已选择13行。


看看查询应该返回多少数据量,还有这个表有多少记录。
SQL> select count(*) from ab44 where aae002='201006';
  COUNT(*)
----------
       576
SQL> select count(*) from ab44;
  COUNT(*)
----------
   3310023

SQL> select 576/3310023 from dual;
576/3310023
-----------
.000174017

查询所需返回的行数仅占表的很小比例,如果有索引的话,应该索引扫描才对。
查看表的索引,发现在aae002字段上有一个复合索引,四个字段组成AAE002, AAE003, AAB001, AAE140。既然有索引,为什么没有使用呢?莫非是缺失统计信息。

查看表、索引、直方图的信息都有。而且统计信息相对还是比较新的。
SQL> select num_rows,blocks,avg_row_len from user_tables where table_name='AB44';
  NUM_ROWS     BLOCKS AVG_ROW_LEN                                               
---------- ---------- -----------                                               
   3310017      44538          84       
SQL> select distinct_keys,clustering_factor,num_rows from  USER_IND_STATISTICS WHERE table_name='AB44' and index_name='PK_AB44';
DISTINCT_KEYS CLUSTERING_FACTOR   NUM_ROWS                                      
------------- ----------------- ----------                                      
      3309447           3299907    3309447  
SQL> SELECT * FROM USER_HISTOGRAMS WHERE table_name='AB44';
略。。。。。。。。。。。。。。。。。。。。。。。。

查询到索引的统计信息的时候,发现索引的聚簇因子非常高,非常接近表的行数。重新分析表,依然如此。
修改聚簇因子后,查看执行计划,已经是索引扫描了。

begin
  dbms_stats.set_index_stats(ownname => 'NCSI',indname => 'PK_AB44',clstfct => '7800');
end;
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------
-------------
Plan hash value: 1618544176
---------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         | 10554 |   865K|   239   (1)| 00:00:03 |
|   1 |  TABLE ACCESS BY INDEX ROWID| AB44    | 10554 |   865K|   239   (1)| 00:00:03 |
|*  2 |   INDEX RANGE SCAN          | PK_AB44 | 10554 |       |    45   (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("AAE002"=201006)
已选择14行。

但是到这里并不能说一定是聚簇因子导致的,因为很可能是还有直方图的因素。查询列AAE002上的唯一值个数为420,而表的记录总数是330万,如果没有直方图的话,ORACLE评估返回的行数应该是3300000/420=7857条记录,按照这个记录量来看,返回的行数占表记录总数的0.2%.根据经验,应该也能使用到索引才对。
于是重新收集统计信息,取消直方图。查看执行计划,还是全表扫描。看来直方图在本例中所占影响因素较小,还是聚簇因子过大惹的祸。

暂时通过修改聚簇因子暂时改善了性能问题,晚上的时候,按照索引字段的顺序重新创建了表。
SQL>create table AB44_TEMP as select * from ab44 where 1=0;
SQL>INSERT /*+ append */INTO AB44_TEMP  SELECT * FROM AB44  ORDER BY AAE002, AAE003, AAB001, AAE140;
SQL>commit;
SQL>drop table ab44;
SQL>alter table ab44_temp rename to ab44;

重新创建索引,分析表。重建后的聚簇因子只有60197,远远小于之前的 3299907。查看执行计划,也对了。

SQL> explain plan for select * from ab44 where aae002=201006;
已解释。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
-------------
Plan hash value: 2627288474
---------------------------------------------------------------------------------------------
| Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |               | 10799 |   885K|   249   (1)| 00:00:03 |
|   1 |  TABLE ACCESS BY INDEX ROWID| AB44          | 10799 |   885K|   249   (1)| 00:00:03 |
|*  2 |   INDEX RANGE SCAN          | AB44_TEMP_IND | 10799 |       |    50   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("AAE002"=201006)
已选择14行。


而且为了验证本例确实是由于聚簇因子过大占了决定因素。我把重建后的表直方图取消掉,重新查询,每一个AAE002的值都是索引扫描了。而之前聚簇因子较大的无直方图的实验,还是全表扫描。进一步证明了本例聚簇因子的影响占了很大比例。
BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(OWNNAME    => 'NCSI',
                                TABNAME    => 'AB44',
                                CASCADE    => TRUE,
                                METHOD_OPT => 'for ALL columns SIZE 1');
END;

SQL>EXPLAIN PLAN FOR SELECT * FROM ab44 WHERE aae002=201002;
SQL>EXPLAIN PLAN FOR SELECT * FROM ab44 WHERE aae002=201006;
SQL>EXPLAIN PLAN FOR SELECT * FROM ab44 WHERE aae002=198701;
SQL>EXPLAIN PLAN FOR SELECT * FROM ab44 WHERE aae002=199101;
SQL>EXPLAIN PLAN FOR SELECT * FROM ab44 WHERE aae002=199804;

  SQL> select object_name,operation,options from plan_table where id=2;
OBJECT_NAME          OPERATION                      OPTIONS
-------------------- ------------------------------ --------------------
AB44_TEMP_IND        INDEX                          RANGE SCAN
AB44_TEMP_IND        INDEX                          RANGE SCAN
AB44_TEMP_IND        INDEX                          RANGE SCAN
AB44_TEMP_IND        INDEX                          RANGE SCAN
AB44_TEMP_IND        INDEX                          RANGE SCAN


查看表有多大
select sum(bytes)/1024/1024 from user_segments where segment_name='X1';
分享到:
评论

相关推荐

    Oracle中聚簇表Cluster Table使用图文详解

    大家通常oracle中的cluster的理解是不准确的,经常和sql server中的cluster index混淆。Cluster是存储一组table的一种方法,这些table共享同一数据块中的某些相同column,并把不同table在这一共享column上值相同的...

    Oracle高级SQL调优:CLUSTER_FACTOR案例研究

    ### Oracle高级SQL调优:CLUSTER_FACTOR案例研究 #### 一、引言 在Oracle数据库管理与优化领域,CLUSTER_FACTOR(简称CF)是衡量索引性能的一个关键指标。它反映了索引条目与其对应的表数据之间物理位置的接近程度...

    Oracle中聚簇表的使用

    在Oracle数据库中,聚簇表(Cluster Table)是一种特殊的数据存储结构,它允许多个表通过共享某些相同的列值来存储在同一个数据块内。这种特性使得相关联的数据能够在物理上更紧密地存储在一起,从而提高查询效率...

    适用于Oracle的Oracle Solaris Cluster数据服务指南

    ### 适用于Oracle的Oracle Solaris Cluster数据服务指南 #### 前言与概述 本指南旨在为使用Oracle Solaris Cluster的用户提供详细的指导和支持,重点介绍如何利用Oracle Solaris Cluster来管理和保护Oracle数据库...

    Oracle VM Blade Cluster

    ### Oracle VM Blade Cluster知识点 #### 一、Oracle VM Blade Cluster参考配置概述 Oracle VM Blade Cluster是一种集成化的解决方案,旨在简化虚拟化基础设施的部署过程。它为IT组织提供了一个经过预先测试和验证...

    Cost-Based.Oracle.Fundamentals

    **聚簇因子**(Clustering Factor, CF)是衡量索引质量的一个关键指标。它反映了索引记录与实际数据行在物理位置上的匹配程度。一个较低的聚簇因子意味着索引记录与其对应的数据行在磁盘上是相邻或接近的,这样在...

    Oracle Cluster Verification Utility

    Cluster Verification Utility (CVU) 是一个随 Oracle Grid Infrastructure/Oracle Clusterware 发布的实用程序。开发此实用程序是为了帮助进行 Oracle Clusterware 和 Oracle Real Application Clusters (RAC) 的...

    FZPU双机安装文 Solaris 10 Oracle 9i SVM Sun Cluster 3.1).doc

    FZPU双机安装文 Solaris 10 Oracle 9i SVM Sun Cluster 3.1).doc

    Oracle_cluster_executionPlan

    Oracle集群和执行计划是数据库管理中的关键概念,尤其在处理大型企业级应用时,它们的重要性不言而喻。Oracle集群是一种高可用性解决方案,通过将多个服务器硬件节点连接在一起,形成一个逻辑整体,共享存储资源,...

    Oracle+ServHA+Cluster+双机热备Linux下详细图文配置教程

    Oracle ServHA Cluster 双机热备是在Linux环境下确保Oracle数据库高可用性的一种解决方案。这个配置教程详细指导了如何在两台Linux服务器上设置共享存储的Oracle数据库,以实现当一台服务器发生故障时,数据库服务...

    Oracle Solaris Cluster 4.10 文档

    Oracle Solaris Cluster 4.10 是一个高度可用性解决方案,专为运行关键业务应用程序的企业设计。这个集群系统提供了一种方法来确保即使在硬件或软件故障时,服务也能持续运行,从而保证业务连续性和数据保护。Oracle...

    行业-69 更新数据的时候,自动维护的聚簇索引到底是什么?l.rar

    聚簇索引是数据库表中的一个关键概念,尤其是在关系型数据库系统中,如MySQL、SQL Server、Oracle等。本篇文章将深入探讨更新数据时自动维护的聚簇索引的本质及其作用。 首先,我们来理解什么是聚簇索引。聚簇索引...

    oracle cluster 检查脚本

    ### Oracle Cluster 检查脚本知识点解析 #### 一、Oracle Cluster简介 Oracle Cluster(通常指的是Oracle Real Application Clusters,简称RAC)是Oracle数据库的一种部署方式,它允许多个数据库实例同时访问一个...

    vmware 下sun cluster 3.2 +oracle 10g双机配置

    本文将深入探讨如何在VMware环境下利用Sun Cluster 3.2技术搭建Oracle 10g Real Application Clusters (RAC)的双机配置。 首先,让我们了解一下Sun Cluster 3.2。这是一个由Sun Microsystems(现已被Oracle公司收购...

    Factor Oracle

    ### Factor Oracle:弱因子识别与在线字符串匹配的高效实验算法 #### 引言与背景 在计算机科学领域,特别是信息检索、数据压缩以及生物信息学等应用中,字符串匹配问题是一个核心研究课题。其基本任务是在一个较大...

    Oracle11g+ServHA Cluster双机热备配置实战

    "Oracle 11g + ServHA Cluster 双机热备配置实战" 本文将指导您如何配置 Oracle 11g 双机热备集群,使用 ServHA Cluster 实现高可用性和故障恢复。 防火墙配置 在配置 ServHA Cluster 之前,需要配置防火墙,以便...

Global site tag (gtag.js) - Google Analytics