After spending some time on finding the root cause and trying out various remedial options I came to the following conclusions:
1) Per default no parallelism is used for the SQL Analyze queries running as part of the statistics gathering job running within the maintenance window. In fact, NO_PARALLEL and NO_PARALLEL_INDEX hints are widely issued by the job - you can check SQL Monitor while the job is running to observe this. However, if you were to run DBMS_STATS.GATHER_DATABASE_STATS(OPTIONS=>'GATHER AUTO') manually in a session, the system parameters for parallelism will be "inherited" by this job, i.e. parallelism may be used. So be very careful with parameters like parallel_threads_per_cpu, parallel_servers_target and parallel_max_servers - as a manual run of the job could end up "killing" database performance for other sessions by starving other sessions for very costly I/O. I strongly recommend that you do a few trial runs starting with low values for these parameters and monitor the database - you can always cancel the job and try with new parameters at any time.
2) The parameter db_file_multiblock_read_count can have a big impact on the efficiency of GATHER_DATABASE_STATS on serialized (non-parallel) maintenance window job execution. The databases in this case had db_file_multiblock_read_count=8 specified (db_block_size=8). This resulted in 2 things: Average I/O size never breached 64KB on table/partition scans/samples (potentially inefficient with RAID stripe sizes of 1MB); and the sample INSERTs into temporary tables from table/partitions samples (INSERT /*+ append */ INTO sys.ora_temp_1_ds_
So the conclusion is that there are ways to improve GATHER_DATABASE_STATS job execution, depending on the environment, regardless of whether it's run manually or through the maintenance window.
No comments:
Post a Comment