首頁 資料庫 mysql教程 Oracle学习之性能优化(四)收集统计信息

Oracle学习之性能优化(四)收集统计信息

Jun 07, 2016 pm 02:56 PM
oracle 最佳化 資訊 效能 收集 統計

emp表有如下数据。 SQLselectename,deptnofromemp;ENAMEDEPTNO----------------------------------------SMITH20ALLEN30WARD30JONES20MARTIN30BLAKE30CLARK10SCOTT20KING10TURNER30ADAMS20JAMES30FORD20MILLER1014rowsselected. 假设我们有如下简单的查询 se

 emp表有如下数据。

SQL> select ename,deptno from emp;

ENAME				   DEPTNO
------------------------------ ----------
SMITH				       20
ALLEN				       30
WARD				       30
JONES				       20
MARTIN				       30
BLAKE				       30
CLARK				       10
SCOTT				       20
KING				       10
TURNER				       30
ADAMS				       20
JAMES				       30
FORD				       20
MILLER				       10

14 rows selected.
登入後複製

假设我们有如下简单的查询

select ename,deptno from emp where ename='RICH' and deptno=10;
登入後複製

那么Oracle在执行查询的时候,是先比较ename字段呢?还是先比较deptno字段呢?

显然先比较deptno再比较ename字段的效率明显低于先比较ename,再比较deptno。 那Oracle究竟如何去判断呢?

我们先查询一张表

SQL> COL COLUMN_NAME FOR A30
SQL> SELECT column_name, num_distinct, density
  FROM dba_tab_columns
 WHERE owner = 'SCOTT' AND table_name = 'EMP';

COLUMN_NAME		       NUM_DISTINCT    DENSITY
------------------------------ ------------ ----------
EMPNO					 14 .071428571
ENAME					 14 .071428571
JOB					  5	    .2
MGR					  6 .166666667
HIREDATE				 13 .076923077
SAL					 12 .083333333
COMM					  4	   .25
DEPTNO					  3 .333333333

8 rows selected.
登入後複製

Oracle其实知道,你的表中存放数据的一些特征,上面语句显示的只是凤毛麟角。通过这些特征,Oracle优化器就能知道如何去查询,使得执行的效率最高。

以上这些信息,我们称之为对象的统计信息。那么如何收集统计信息呢?


一、 analyze 命令

使用analyze命令可以收集统计信息,如:

  • 收集或删除对象的统计信息

  • 验证对象的结构

  • 确定table 或cluster的migrated 和chained rows。

示例:

SQL> create user anal identified by anal ;

User created.

SQL> grant resource,connect to anal;

Grant succeeded.

SQL> grant select any dictionary to anal;

Grant succeeded.

SQL> conn anal/anal
Connected.
SQL> create table t1 as select * from dba_objects;
SQL> create table t2 as select * from dba_objects;
SQL> create table t3 as select * from dba_objects;
SQL> create table t4 as select * from  dba_objects;
SQL> create table t5 as select * from dba_objects;
SQL> create table t6 as select * from dba_objects;
SQL>  create unique index pk_t1_idx on t1(object_id);
SQL>  create unique index pk_t2_idx on t2(object_id);
SQL>  create unique index pk_t3_idx on t3(object_id);
SQL>  create unique index pk_t4_idx on t4(object_id);
SQL>  create unique index pk_t5_idx on t5(object_id);
SQL>  create unique index pk_t6_idx on t6(object_id);
登入後複製

我们先查看一下统计信息是否存在

查看表的统计信息

SQL> select table_name, num_rows, blocks, empty_blocks
      from user_tables
     where table_name in ('T1', 'T2', 'T3', 'T4', 'T5','T6');
登入後複製

查看字段统计信息

select table_name,
       column_name,
       num_distinct,
       low_value,
       high_value,
       density
  from user_tab_columns
 where table_name in ('T1', 'T2', 'T3', 'T4','T5','T6');
登入後複製

查看索引统计信息

SQL> col table_name for a30
SQL> col index_name for a30
SELECT table_name,
       index_name,
       blevel,
       leaf_blocks,
       distinct_keys,
       avg_leaf_blocks_per_key avg_leaf_blocks,
       avg_data_blocks_per_key avg_data_blocks,
       clustering_factor,
       num_rows
  FROM user_indexes

TABLE_NAME		       INDEX_NAME			  BLEVEL LEAF_BLOCKS DISTINCT_KEYS AVG_LEAF_BLOCKS AVG_DATA_BLOCKS CLUSTERING_FACTOR   NUM_ROWS
------------------------------ ------------------------------ ---------- ----------- ------------- --------------- --------------- ----------------- ----------
T6			       PK_T6_IDX			       1	 155	     74564		 1		 1		1174	  74564
T5			       PK_T5_IDX			       1	 155	     74563		 1		 1		1174	  74563
T4			       PK_T4_IDX			       1	 155	     74562		 1		 1		1174	  74562
T3			       PK_T3_IDX			       1	 155	     74561		 1		 1		1174	  74561
T2			       PK_T2_IDX			       1	 155	     74560		 1		 1		1174	  74560
T1			       PK_T1_IDX			       1	 155	     74559		 1		 1		1174	  74559

6 rows selected.
登入後複製

表没有任何统计数据,但是索引已经有统计信息,可见在建立表的时候会默认收集统计信息。

先将索引的统计信息删除

SQL> analyze table t1 delete statistics;
analyze table t2 delete statistics;
analyze table t3 delete statistics;
analyze table t4 delete statistics;
analyze table t5 delete statistics;
analyze table t6 delete statistics;
登入後複製

验证索引上是否还存在统计信息

SELECT table_name,
       index_name,
       blevel,
       leaf_blocks,
       distinct_keys,
       avg_leaf_blocks_per_key avg_leaf_blocks,
       avg_data_blocks_per_key avg_data_blocks,
       clustering_factor,
       num_rows
  FROM user_indexes
登入後複製

执行统计信息命令,并查看统计信息有无变化

analyze table t1 compute statistics for table;

--针对表收集信息,查看user_tables

analyze table t2 compute statistics for all columns;

--针对表字段收集信息,查看user_tab_columns

analyze table t3 compute statistics for all indexed columns;

--收集索引字段信息

analyze table t4 compute statistics;

--收集表,表字段,索引信息

analyze table t5 compute statistics for all indexes;

--收集索引信息

analyze table t6 compute statistics for table for all indexes for all columns;

--收集表,表字段,索引信息


二、DBMS_STATS包

Oracle推荐使用DBMS_STATS这个包来收集统计信息。这个包的功能非常多。可以收集数据库级别、schema级别及表级别的统计信息。还可以对统计信息删除、锁定、导出、导入等。我们以最常用的表级别统计为例说明DBMS_STATS该如何使用。

收集的统计信存储在dba_tab_statistics、dba_ind_statistics和dba_tab_col_statistics表中。

DBMS_STATS.GATHER_TABLE_STATS (
   ownname          VARCHAR2, 
   tabname          VARCHAR2, 
   partname         VARCHAR2 DEFAULT NULL,
   estimate_percent NUMBER   DEFAULT to_estimate_percent_type 
                                                (get_param('ESTIMATE_PERCENT')), 
   block_sample     BOOLEAN  DEFAULT FALSE,
   method_opt       VARCHAR2 DEFAULT get_param('METHOD_OPT'),
   degree           NUMBER   DEFAULT to_degree_type(get_param('DEGREE')),
   granularity      VARCHAR2 DEFAULT GET_PARAM('GRANULARITY'), 
   cascade          BOOLEAN  DEFAULT to_cascade_type(get_param('CASCADE')),
   stattab          VARCHAR2 DEFAULT NULL, 
   statid           VARCHAR2 DEFAULT NULL,
   statown          VARCHAR2 DEFAULT NULL,
   no_invalidate    BOOLEAN  DEFAULT  to_no_invalidate_type (
                                     get_param('NO_INVALIDATE')),
   stattype         VARCHAR2 DEFAULT 'DATA',
   force            BOOLEAN  DEFAULT FALSE);
登入後複製

参数说明如下:

650) this.width=650;" title="02.PNG" alt="wKiom1XTQfjjM5MQAAK5UvU0I1U436.jpg" />

650) this.width=650;" title="03.PNG" alt="wKiom1XTQgPC6wJhAAXhcpo1cG0620.jpg" />

650) this.width=650;" title="04.PNG" alt="wKioL1XTRBujG-h6AAYphtOucrs231.jpg" />

650) this.width=650;" title="05.PNG" alt="wKiom1XTQh6CXHdEAAJ-9MoVv0U797.jpg" />


示例:

SQL> col table_name for a30
SQL> SELECT table_name,
       num_rows,
       blocks,
       empty_blocks,
       avg_row_len
  FROM user_tab_statistics;

TABLE_NAME			 NUM_ROWS     BLOCKS EMPTY_BLOCKS AVG_ROW_LEN
------------------------------ ---------- ---------- ------------ -----------
T1				    74559	1088		0	   98
T2
T3
T4
T5
T6

6 rows selected.
登入後複製


删除统计信息

DBMS_STATS.DELETE_TABLE_STATS (
 ownname VARCHAR2,
 tabname VARCHAR2,
 partname VARCHAR2 DEFAULT NULL,
 stattab VARCHAR2 DEFAULT NULL,
 statid VARCHAR2 DEFAULT NULL,
 cascade_parts BOOLEAN DEFAULT TRUE,
 cascade_columns BOOLEAN DEFAULT TRUE,
 cascade_indexes BOOLEAN DEFAULT TRUE,
 statown VARCHAR2 DEFAULT NULL,
 no_invalidate BOOLEAN DEFAULT to_no_invalidate_type (
 get_param('NO_INVALIDATE')),
 force BOOLEAN DEFAULT FALSE);
登入後複製

锁定统计信息

DBMS_STATS.LOCK_TABLE_STATS (
 ownname VARCHAR2,
 tabname VARCHAR2);
登入後複製

锁定以后就不能再执行统计信息

SQL> exec dbms_stats.lock_table_stats(user,'T1');

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_table_stats(user,'t1',cascade=>true);
BEGIN dbms_stats.gather_table_stats(user,'t1',cascade=>true); END;

*
ERROR at line 1:
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512: at "SYS.DBMS_STATS", line 23829
ORA-06512: at "SYS.DBMS_STATS", line 23880
ORA-06512: at line 1
登入後複製

导出、导入统计信息

  1. 要导出统计信息首先要建立一个统计表

语法:

DBMS_STATS.CREATE_STAT_TABLE (
   ownname  VARCHAR2, 
   stattab  VARCHAR2,
   tblspace VARCHAR2 DEFAULT NULL);
登入後複製
SQL> exec DBMS_STATS.CREATE_STAT_TABLE (user,'STAT_TMP','SYSAUX');

PL/SQL procedure successfully completed.
登入後複製

2. 将表t1统计信息导出

DBMS_STATS.EXPORT_TABLE_STATS (
   ownname         VARCHAR2, 
   tabname         VARCHAR2, 
   partname        VARCHAR2 DEFAULT NULL,
   stattab         VARCHAR2, 
   statid          VARCHAR2 DEFAULT NULL,
   cascade         BOOLEAN  DEFAULT TRUE,
   statown         VARCHAR2 DEFAULT NULL,
   stat_category   VARCHAR2 DEFAULT DEFAULT_STAT_CATEGORY);
登入後複製
SQL> EXEC DBMS_STATS.EXPORT_TABLE_STATS (ownname=>USER,tabname=>'T1',stattab=>'STAT_TMP');

PL/SQL procedure successfully completed.
登入後複製

3. 导入统计信息

语法:

DBMS_STATS.IMPORT_TABLE_STATS (
   ownname         VARCHAR2, 
   tabname         VARCHAR2,
   partname        VARCHAR2 DEFAULT NULL,
   stattab         VARCHAR2, 
   statid          VARCHAR2 DEFAULT NULL,
   cascade         BOOLEAN  DEFAULT TRUE,
   statown         VARCHAR2 DEFAULT NULL,
   no_invalidate   BOOLEAN DEFAULT to_no_invalidate_type(
                                    get_param('NO_INVALIDATE')),
   force           BOOLEAN DEFAULT FALSE,
   stat_category   VARCHAR2 DEFAULT DEFAULT_STAT_CATEGORY);
登入後複製
SQL> exec dbms_stats.UNlock_table_stats(user,'T1');

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.delete_table_stats(user,'T1');

PL/SQL procedure successfully completed.

SQL> EXEC DBMS_STATS.IMPORT_TABLE_STATS (ownname=>USER,tabname=>'T1',stattab=>'STAT_TMP');

PL/SQL procedure successfully completed.

SQL> SELECT table_name,
       num_rows,
       blocks,
       empty_blocks,
       avg_row_len
  FROM user_tab_statistics;  2    3    4    5    6  

TABLE_NAME			 NUM_ROWS     BLOCKS EMPTY_BLOCKS AVG_ROW_LEN
------------------------------ ---------- ---------- ------------ -----------
T1				    74559	1088		0	   98
T2
T3
T4
T5
T6
STAT_TMP

7 rows selected.
登入後複製


如果是分区表,新的分区来不及收集统计系统,可以使用其它的分区统计信息来生成新分区的统计信息

DBMS_STATS.COPY_TABLE_STATS (
   ownname          VARCHAR2, 
   tabname          VARCHAR2, 
   srcpartname      VARCHAR2,
   dstpartname      VARCHAR2, 
   scale_factor     VARCHAR2 DEFAULT 1,
   force            BOOLEAN DEFAULT FALSE);
登入後複製

如果表还没有统计信息,那么在执行sql语句时,Oracle会动态的采样表中的一部分数据,生成统计信息。

SQL> show parameter optimizer_dynamic_sampling ;

NAME				     TYPE			       VALUE
------------------------------------ --------------------------------- ------------------------------
optimizer_dynamic_sampling	     integer			       2
登入後複製
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1421
52
Laravel 教程
1315
25
PHP教程
1266
29
C# 教程
1239
24
oracle打不開怎麼辦 oracle打不開怎麼辦 Apr 11, 2025 pm 10:06 PM

Oracle 打不開的解決辦法包括:1. 啟動數據庫服務;2. 啟動監聽器;3. 檢查端口衝突;4. 正確設置環境變量;5. 確保防火牆或防病毒軟件未阻止連接;6. 檢查服務器是否已關閉;7. 使用 RMAN 恢復損壞的文件;8. 檢查 TNS 服務名稱是否正確;9. 檢查網絡連接;10. 重新安裝 Oracle 軟件。

oracle游標關閉怎麼解決 oracle游標關閉怎麼解決 Apr 11, 2025 pm 10:18 PM

解決 Oracle 游標關閉問題的方法包括:使用 CLOSE 語句顯式關閉游標。在 FOR UPDATE 子句中聲明游標,使其在作用域結束後自動關閉。在 USING 子句中聲明游標,使其在關聯的 PL/SQL 變量關閉時自動關閉。使用異常處理確保在任何異常情況下關閉游標。使用連接池自動關閉游標。禁用自動提交,延遲游標關閉。

oracle怎麼循環創建游標 oracle怎麼循環創建游標 Apr 12, 2025 am 06:18 AM

Oracle 中,FOR LOOP 循環可動態創建游標, 步驟為:1. 定義游標類型;2. 創建循環;3. 動態創建游標;4. 執行游標;5. 關閉游標。示例:可循環創建游標,顯示前 10 名員工姓名和工資。

HDFS配置CentOS需要哪些步驟 HDFS配置CentOS需要哪些步驟 Apr 14, 2025 pm 06:42 PM

在CentOS系統上搭建Hadoop分佈式文件系統(HDFS)需要多個步驟,本文提供一個簡要的配置指南。一、前期準備安裝JDK:在所有節點上安裝JavaDevelopmentKit(JDK),版本需與Hadoop兼容。可從Oracle官網下載安裝包。環境變量配置:編輯/etc/profile文件,設置Java和Hadoop的環境變量,使系統能夠找到JDK和Hadoop的安裝路徑。二、安全配置:SSH免密登錄生成SSH密鑰:在每個節點上使用ssh-keygen命令

oracle日誌寫滿怎麼辦 oracle日誌寫滿怎麼辦 Apr 12, 2025 am 06:09 AM

Oracle 日誌文件寫滿時,可採用以下解決方案:1)清理舊日誌文件;2)增加日誌文件大小;3)增加日誌文件組;4)設置自動日誌管理;5)重新初始化數據庫。在實施任何解決方案前,建議備份數據庫以防數據丟失。

甲骨文在商業世界中的作用 甲骨文在商業世界中的作用 Apr 23, 2025 am 12:01 AM

Oracle不僅是數據庫公司,還是雲計算和ERP系統的領導者。 1.Oracle提供從數據庫到雲服務和ERP系統的全面解決方案。 2.OracleCloud挑戰AWS和Azure,提供IaaS、PaaS和SaaS服務。 3.Oracle的ERP系統如E-BusinessSuite和FusionApplications幫助企業優化運營。

oracle數據庫怎麼停止 oracle數據庫怎麼停止 Apr 12, 2025 am 06:12 AM

要停止 Oracle 數據庫,請執行以下步驟:1. 連接到數據庫;2. 優雅關機數據庫(shutdown immediate);3. 完全關機數據庫(shutdown abort)。

oracle視圖怎麼導出 oracle視圖怎麼導出 Apr 12, 2025 am 06:15 AM

可以通過 EXP 實用程序導出 Oracle 視圖:登錄 Oracle 數據庫。啟動 EXP 實用程序,指定視圖名稱和導出目錄。輸入導出參數,包括目標模式、文件格式和表空間。開始導出。使用 impdp 實用程序驗證導出。

See all articles