Number of distinct values (NDV) & synopsis & Histogram gather speed

Number of distinct values (NDV)   & synopsis & Histogram gather speed

Number of distinct values (NDV)   & synopsis

Pre 11g – Sampling based
Sample the data, get NDV from sample and scale
Computation involves sort and may spill to disk -> expensive
Can not scale the NDV well for skewed columns -> inaccurate NDV

11g – Approximate NDV
Create an auxiliary structure, synopsis by scanning data
Synopsis can be viewed as a sample of distinct values
The structure uses bounded amount of memory
Synopses on different segments of table can be aggregated to generate a single synopsis
NDV can be accurately  and efficiently derived from synopsis

 

Synopsis is a collection of hash values of distinct values
The hash value has the following properties
Bits are independent of each other
Each bit has same probability of being 0 or 1

 

 

 

SQL> select bytes/1024/1024 from dba_segments where segment_name='LARGE_HISTOGRAM';
BYTES/1024/1024
---------------
2333
SQL> 
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
PL/SQL Release 10.2.0.5.0 - Production
CORE    10.2.0.5.0      Production
TNS for Linux: Version 10.2.0.5.0 - Production
NLSRTL Version 10.2.0.5.0 - Production
SQL> set timing on;
SQL> 
SQL> exec dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 1', estimate_percent=>100);
PL/SQL procedure successfully completed.
Elapsed: 00:02:01.14
SQL> alter system flush buffer_cache;
System altered.
Elapsed: 00:00:00.05
SQL> exec dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 1', estimate_percent=>100);
PL/SQL procedure successfully completed.
Elapsed: 00:02:01.16
SQL> alter system flush buffer_cache;
System altered.
Elapsed: 00:00:00.03
SQL> exec dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>100);
BEGIN dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>100); END;
*
ERROR at line 1:
ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
ORA-06512: at "SYS.DBMS_STATS", line 15027
ORA-06512: at "SYS.DBMS_STATS", line 15049
ORA-06512: at line 1
Elapsed: 00:00:28.87
SQL> alter system set pga_aggregate_target=1000M;
System altered.
Elapsed: 00:00:00.01
SQL> show parameter work
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
fileio_network_adapters              string
workarea_size_policy                 string      AUTO
SQL> exec dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>100);
BEGIN dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>100); END;
*
ERROR at line 1:
ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
ORA-06512: at "SYS.DBMS_STATS", line 15027
ORA-06512: at "SYS.DBMS_STATS", line 15049
ORA-06512: at line 1
Elapsed: 00:00:28.65
SQL> alter tablespace temp add tempfile size 10g;
Tablespace altered.
Elapsed: 00:00:00.08
SQL> alter system flush buffer_cache;
System altered.
Elapsed: 00:00:00.04
SQL> select * from v$sort_usage;
no rows selected
Elapsed: 00:00:00.03
SQL>  exec dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>100);
SQL>  exec dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>100);
BEGIN dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>100); END;
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [kcfrbd_1], [0], [131068], [], [],
[], [], []
ORA-06512: at "SYS.DBMS_STATS", line 15027
ORA-06512: at "SYS.DBMS_STATS", line 15049
ORA-06512: at line 1
Elapsed: 00:00:30.63
SQL> create temporary tablespace temp1 tempfile size 10g;
Tablespace created.
Elapsed: 00:00:00.11
SQL> alter database default temporary tablespace temp1;
Database altered.
Elapsed: 00:00:00.03
SQL> alter tablespace temp1 add tempfile size 10g;
Tablespace altered.
Elapsed: 00:00:00.02
SQL>  exec dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>100);
BEGIN dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>100); END;
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [kcfrbd_3], [2], [673281], [1],
[673280], [673280], [], []
ORA-06512: at "SYS.DBMS_STATS", line 15027
ORA-06512: at "SYS.DBMS_STATS", line 15049
ORA-06512: at line 1
Elapsed: 00:00:31.63
SQL> exec dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>1);
BEGIN dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE 100',estimate_percent=>1); END;
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [kcfrbd_3], [2], [673281], [1],
[673280], [673280], [], []
ORA-06512: at "SYS.DBMS_STATS", line 15027
ORA-06512: at "SYS.DBMS_STATS", line 15049
ORA-06512: at line 1
Elapsed: 00:00:01.72
SQL> exec dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE AUTO',estimate_percent=>1);
PL/SQL procedure successfully completed.
Elapsed: 00:00:03.57
SQL> exec dbms_stats.gather_table_stats(USER,'LARGE_HISTOGRAM',method_opt=>'FOR ALL COLUMNS SIZE AUTO',estimate_percent=>100);
PL/SQL procedure successfully completed.
Elapsed: 00:02:02.13
11.2.0.3

 

相关BUG:

Bug 8663644  Slow Histograms gathering / Histograms are gathered serially

Bug 13583722 – slow incremental stats gather from global histogram gathers (Doc ID 13583722.8) 等

 

Comment

*

沪ICP备14014813号

沪公网安备 31010802001379号