Concurrent stats gathering was introduced with 11g (11.2.0.2) database
– ability to gather statistics on multiple tables and (sub)partitions
concurrently to reduce the overall time it takes to gather statistics by
enabling oracle to fully utilize multiprocessor environments.
If you call dbms_stats.gather_table_stats on a partitioned table when
CONCURRENT is set to true, Oracle will create a separate statistics gathering
job for each (sub)partition in the table. The Job Scheduler will decide how many
of these jobs will execute concurrently, and how many will be queued based on
available system resources. As the currently running jobs complete, more jobs
will be dequeued and executed until all (sub)partitions have had their
statistics gathered on them.
If you gather the statistics using gather_database_stats or
gather_schema_stats, then Oracle will create a separate statistics gathering
job for each non-partitioned table, and each (sub)partition for the partitioned
table.Each (sub)partitioned table will also have a coordinator job that manages
its (sub)partition jobs. The database will then run as many concurrent jobs as
possible, and queue the remaining jobs until the executing jobs complete
rajesh@ORA11G> select count(*) from big_table ;
COUNT(*)
----------
10000000
1 row selected.
rajesh@ORA11G> create table t1
2 partition by hash(object_id)
3 ( partition p1,
4 partition p2,
5 partition p3,
6 partition p4 )
7 as
8 select * from big_table;
Table created.
rajesh@ORA11G> create table t2
2 partition by hash(object_id)
3 ( partition p1,
4 partition p2,
5 partition p3,
6 partition p4 )
7 as
8 select * from big_table;
Table created.
rajesh@ORA11G>
rajesh@ORA11G> select table_name,partitioned
2 from user_tables ;
TABLE_NAME PAR
--------------- ---
BIG_TABLE NO
T2 YES
T1 YES
3 rows selected.
So
we have totally three tables in the schema, out which two are partitioned and
one is non-partitioned.
When
CONCURRENT statistics were enabled in 11g (11.2.0.4) database - it goes this
way.
rajesh@ORA11G> select dbms_stats.get_prefs('CONCURRENT') from
dual;
DBMS_STATS.GET_PREFS('CONCURRENT')
------------------------------------------------------------------------------------
FALSE
1 row selected.
rajesh@ORA11G> exec dbms_stats.set_global_prefs('CONCURRENT','TRUE');
PL/SQL procedure successfully completed.
rajesh@ORA11G> select dbms_stats.get_prefs('CONCURRENT') from
dual;
DBMS_STATS.GET_PREFS('CONCURRENT')
------------------------------------------------------------------------------------
TRUE
1 row selected.
rajesh@ORA11G> exec dbms_stats.gather_schema_stats(user);
/* Monitoring from a different
connections
rajesh@ORA11G> select job_name,state,comments
2 from dba_scheduler_jobs
3 where job_class like 'CONC%'
4 order by 1 ;
JOB_NAME
STATE COMMENTS
------------------------------ ---------------
-----------------------------------
ST$SD2581_1
RUNNING
"RAJESH"."BIG_TABLE".
ST$SD2581_2 RUNNING "RAJESH"."T1".
ST$T2582_1
RUNNING RAJESH.T1.P1
ST$T2582_2
RUNNING RAJESH.T1.P2
ST$T2582_3
RUNNING RAJESH.T1.P3
ST$T2582_4
RUNNING RAJESH.T1.P4
ST$T2582_5
RUNNING RAJESH.T1.
7 rows selected.
rajesh@ORA11G> show parameter job_queue
NAME
TYPE VALUE
--------------------------------------------- -----------
------------------------
job_queue_processes integer 1000
rajesh@ORA11G>
/*
All
statistics collection job names start with 'ST$' for easy identification. The
jobs whose name start with ST$T###_### are created by a coordinator job for a
partitioned table, and works (sub)partition of the table.
The
jobs whose name begin with ST$SD###_### are created for a table in a schema or
database, and either works as a coordinator for its partition level jobs (if
the table is partitioned), or directly performs the statistics collection for
the table (if the table is not partitioned).
So
looking at the output from DBA_SCHEDULER_JOBS in 11g database, it confirms that
only one partitioned table can be run concurrently, even though the schema has
more than one partitioned tables.
But
when repeating this test in 12c (12.1.0.2) shows this.
rajesh@ORA12C> select table_name,partitioned
2 from user_tables ;
TABLE_NAME PAR
--------------- ---
BIG_TABLE NO
T1 YES
T2 YES
3 rows selected.
rajesh@ORA12C> select dbms_stats.get_prefs('CONCURRENT') from
dual;
DBMS_STATS.GET_PREFS('CONCURRENT')
-------------------------------------------------------------------------------------
OFF
1 row selected.
rajesh@ORA12C> exec
dbms_stats.set_global_prefs('CONCURRENT','ALL');
PL/SQL procedure successfully completed.
rajesh@ORA12C> select dbms_stats.get_prefs('CONCURRENT') from
dual;
DBMS_STATS.GET_PREFS('CONCURRENT')
-------------------------------------------------------------------------------------
ALL
1 row selected.
rajesh@ORA12C> exec dbms_stats.gather_schema_stats(user);
/* Monitoring from a different connections
rajesh@ORA12C> column job_name format a30
rajesh@ORA12C> column comments format a70
rajesh@ORA12C> select job_name,state,comments
2 from dba_scheduler_jobs
3 where job_class like 'CONC%'
4 order by 1 ;
JOB_NAME STATE COMMENTS
--------------- ---------
-----------------------------------------------------------
ST$SD5402_1 RUNNING "RAJESH"."BIG_TABLE"
ST$SD5402_2 RUNNING "RAJESH"."T1"
ST$SD5402_3 RUNNING "RAJESH"."T2"
ST$T5442_1_B3
RUNNING
"RAJESH"."T1"."P1";"RAJESH"."T1"."P2";"RAJESH"."T1"."P3"
ST$T5442_2_B2
RUNNING
"RAJESH"."T1"."P4";"RAJESH"."T1"
ST$T5482_1_B2
RUNNING
"RAJESH"."T2"."P1";"RAJESH"."T2"."P2"
ST$T5482_2_B2 RUNNING "RAJESH"."T2"."P3";"RAJESH"."T2"."P4"
ST$T5482_3
RUNNING
"RAJESH"."T2"
8 rows selected.
rajesh@ORA12C> show parameter job_queue_
NAME
TYPE VALUE
--------------------------------------------- -----------
-------------------------
job_queue_processes integer 1000
rajesh@ORA12C>
*/