When a valid SQL statment is sent to the server for the first time,Oracle produces an execution plan that describles how to retrieve the necessary data. the execution plan could be generated using one of two optimizers.
The DBMS_STATS package gathering statistics.Oracle list a number of benefits to using it including parallel execution, long term storage of statistics and transfer of statistics between servers.
Table statistics can be gathered for the database:
- [oracle@oracle-db-19c ~]$
- [oracle@oracle-db-19c ~]$ sqlplus / as sysdba
-
- SQL*Plus: Release 19.0.0.0.0 - Production on Mon Nov 28 15:51:41 2022
- Version 19.3.0.0.0
-
- Copyright (c) 1982, 2019, Oracle. All rights reserved.
-
-
- Connected to:
- Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
- Version 19.3.0.0.0
-
- SQL> alter session set container=PDB1;
-
- Session altered.
-
- SQL> EXEC DBMS_STATS.gather_database_stats;
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.gather_database_stats(estimate_percent => 15);
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.gather_database_stats(estimate_percent => 15, cascade => TRUE);
-
- PL/SQL procedure successfully completed.
-
- SQL>
Table statistics can be gathered for the schema:
- SQL>
- SQL> EXEC DBMS_STATS.gather_schema_stats('SCOTT');
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.gather_schema_stats('SCOTT',estimate_percent=> 15);
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.gather_schema_stats('SCOTT',estimate_percent=> 15,cascade => TRUE);
-
- PL/SQL procedure successfully completed.
-
- SQL>
Table statistics can be gathered for the table:
- SQL>
- SQL> EXEC DBMS_STATS.gather_table_stats('SCOTT', 'EMP');
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.gather_table_stats('SCOTT', 'EMP', estimate_percent => 15);
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.gather_table_stats('SCOTT', 'EMP', estimate_percent => 15, cascade => TRUE);
-
- PL/SQL procedure successfully completed.
-
- SQL>
Table statistics can be gathered for the partition:
- SQL>
- SQL> EXEC DBMS_STATS.gather_dictionary_stats;
-
- PL/SQL procedure successfully completed.
-
- SQL>
Index statistics can be gathered explicitly using the GATHER_INDEX_STATS
procedure.
-
-
- SQL> EXEC DBMS_STATS.gather_index_stats('SCOTT', 'PK_EMP');
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.gather_index_stats('SCOTT', 'PK_EMP', estimate_percent => 15);
-
- PL/SQL procedure successfully completed.
-
- SQL>
The current statistics information is available from the data dictionary views for the specific objects (DBA, ALL and USER views).
Histogram information is available from the following views.
Table, column and index statistics can be deleted using the relevant delete procedures.
- SQL>
- SQL> EXEC DBMS_STATS.delete_database_stats;
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.delete_schema_stats('SCOTT');
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.delete_table_stats('SCOTT', 'EMP');
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.delete_column_stats('SCOTT', 'EMP', 'EMPNO');
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.delete_index_stats('SCOTT', 'PK_EMP');
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.delete_dictionary_stats;
-
- PL/SQL procedure successfully completed.
-
- SQL>
The GATHER_SYSTEM_STATS
procedure gathers statistics relating to the performance of your systems I/O and CPU. Giving the optimizer this information makes its choice of execution plan more accurate, since it is able to weigh the relative costs of operations using both the CPU and I/O profiles of the system.
There are two possible types of system statistics:
- SQL> show user
- USER is "SYS"
- SQL> EXEC DBMS_STATS.gather_system_stats;
-
- PL/SQL procedure successfully completed.
-
- SQL>
- -- Manually start and stop to sample a representative time (several hours) of system activity.
-
- SQL>
- SQL> EXEC DBMS_STATS.gather_system_stats('start');
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.gather_system_stats('stop');
-
- PL/SQL procedure successfully completed.
-
- SQL> show user;
- USER is "SYS"
- SQL>
-
-
-
- -- Sample from now until a specific number of minutes.
- DBMS_STATS.gather_system_stats('interval', interval => 180);
current system statistics can be displayed by querying the AUX_STATS$ table.
- SQL>
- SQL> select pname,pval1 from sys.aux_stats$ where sname='SYSSTATS_MAIN';
-
- PNAME PVAL1
- ------------------------------ ----------
- CPUSPEEDNW 2121
- IOSEEKTIM 10
- IOTFRSPEED 4096
- SREADTIM .2
- MREADTIM .224
- CPUSPEED 2122
- MBRC 10
- MAXTHR
- SLAVETHR
-
- 9 rows selected.
-
- SQL>
The DELETE_SYSTEM_STATS
procedure will delete all workload stats and replace previously gathered noworkload stats with the default values.
- SQL>
- SQL> EXEC DBMS_STATS.delete_system_stats;
-
- PL/SQL procedure successfully completed.
-
- SQL>
You only need to update your system statistics when something major has happened to your systems hardware or workload profile.
EXEC DBMS_STATS.set_system_stats('iotfrspeed', 4096);
Fixed Object Stats
the GATHER_FIXED_OBJECTS_STATS
procedure gathers statistics on the X$
tables, which sit underneath the V$
dynamic performance views. The X$
tables are not really tables at all, but a window on to the memory structures in the Oracle kernel. Fixed object stats are not gathered automatically, so you need to gather them manually at a time when the database is in a representative level of activity.
- SQL> EXEC DBMS_STATS.gather_fixed_objects_stats;
-
- PL/SQL procedure successfully completed.
-
- SQL>
Major changes to initialization parameters or system activity should signal you to gather fresh stats, but under normal running this does not need to be done on a regular basis.
The stats are removed using the DELETE_FIXED_OBJECTS_STATS
procedure.
- SQL>
- SQL> EXEC DBMS_STATS.delete_fixed_objects_stats;
-
- PL/SQL procedure successfully completed.
-
- SQL>
To prevent statistics being overwritten, you can lock&unlock the stats at schema, table or partition level.
- SQL>
- SQL> EXEC DBMS_STATS.lock_schema_stats('SCOTT');
-
- PL/SQL procedure successfully completed.
-
- SQL> EXEC DBMS_STATS.unlock_schema_stats('SCOTT');
-
- PL/SQL procedure successfully completed.
-
- SQL>
- SQL>
- SQL> EXEC DBMS_STATS.lock_table_stats('SCOTT', 'EMP');
-
- PL/SQL procedure successfully completed.
-
- SQL>
- SQL> EXEC DBMS_STATS.unlock_table_stats('SCOTT', 'EMP');
-
- PL/SQL procedure successfully completed.
-
- SQL>
- EXEC DBMS_STATS.lock_partition_stats('SCOTT', 'EMP', 'EMP_PART1');
- EXEC DBMS_STATS.unlock_partition_stats('SCOTT', 'EMP', 'EMP_PART1');
It is possible to transfer statistics between servers allowing consistent execution plans between servers with varying amounts of data. First the statistics must be collected into a statistics table. In the following examples the statistics for the APPSCHEMA user are collected into a new table, STATS_TABLE, which is owned by DBASCHEMA.
- EXEC DBMS_STATS.create_stat_table('DBASCHEMA','STATS_TABLE');
- EXEC DBMS_STATS.export_schema_stats('APPSCHEMA','STATS_TABLE',NULL,'DBASCHEMA');
This table can then be transfered to another server using your preferred method (Export/Import, SQL*Plus COPY etc.) and the stats imported into the data dictionary as follows.
- EXEC DBMS_STATS.import_schema_stats('APPSCHEMA','STATS_TABLE',NULL,'DBASCHEMA');
- EXEC DBMS_STATS.drop_stat_table('DBASCHEMA','STATS_TABLE');
EXEC DBMS_STATS.set_param('DEGREE', '5');
the SET_PARAM
procedure was deprecated in favor of a layered approach to preferences. The four levels of preferences are amended with the following procedures.
SET_GLOBAL_PREFS
: Used to set global preferences, including some specific to the automatic stats collection job.SET_DATABASE_PREFS
: Sets preferences for the whole database.SET_SCHEMA_PREFS
: Sets preferences for a specific schema.SET_TABLE_PREFS
: Sets preferences for a specific table.