Sunteți pe pagina 1din 10

ORACLE DBA TUNING

Many DBAs do their best to get a 99% or better buffer cache hit ratio, but quickly discover that the performance of their database isn't improving as the hit ratio gets better.

Here is a query to get your database's current hit ratio: SQL> -- Get initial Buffer Hit Ratio reading... SQL> SELECT ROUND((1-(phy.value / (cur.value + con.value)))*100,2) "Cache Hit Ratio" 2 FROM v$sysstat cur, v$sysstat con, v$sysstat phy 3 WHERE cur.name = 'db block gets' 4 5 6 / AND con.name = 'consistent gets' AND phy.name = 'physical reads'

Cache Hit Ratio --------------90.75

However, to show how meaningless this number is, let's artificially increase it: SQL> SQL> -- Let's artificially increase the buffer hit ratio... SQL> DECLARE 2 v_dummy dual.dummy%TYPE; 3 BEGIN 4 FOR I IN 1..10000000 LOOP

SELECT dummy INTO v_dummy FROM dual;

6 END LOOP; 7 END; 8 /

PL/SQL procedure successfully completed.

Let's see what happened: SQL> SQL> -- Let's measure it again... SQL> SELECT ROUND((1-(phy.value / (cur.value + con.value)))*100,2) "Cache Hit Ratio" 2 FROM v$sysstat cur, v$sysstat con, v$sysstat phy 3 WHERE cur.name = 'db block gets' 4 5 6 / AND con.name = 'consistent gets' AND phy.name = 'physical reads'

Cache Hit Ratio --------------99.94

Conclusion: Don't even bother trying to tune the Buffer Hit Ratio!

There are better ways to tune now. The Oracle Wait Interface (OWI) provides exact details. No need to rely on fuzzy meaningless counters anymore.

PRACTICE:

SQL> SELECT ROUND((1-(phy.value / (cur.value + con.value)))*100,2) "Cache Hit Ratio" 2 3 4 5 6 FROM v$sysstat cur, v$sysstat con, v$sysstat phy WHERE cur.name = 'db block gets' AND con.name = 'consistent gets' AND phy.name = 'physical reads' /

Cache Hit Ratio --------------94.65

DEMO ON ROW MIGRATION AND ROW CHAINING DEMO ON ROW MIGRATION AND ROW CHAINING Migration and Chaining Of Rows Row Chaining : When the data for a row in a table is too large to fit into a single data block, then the Oracle server stores the data for the row in a chain of data blocks if the data is too large to fit an empty block, this process is called Row Chaining. Row Migration : When an update statement increases the amount of data in a row so that the row no longer fits in its data block. The oracle server tries to find another block with enough free space to hold the entire row. If such a block is available, the Oracle server moves the entire row to the new block. The Oracle server keeps the original piece of a migrated row to point to the new block containing the actual row does not change. Indexes are not updated, so they point to the original row location. This process is called Row Migration. Migration and Chaining have a negative effect on performance

Insert and Update statement that cause migration and chaining perform poorly, because they perform additional processing. Queries that use an index to select migrated or chained rows must perform additional I/Os. Causes Of Row Migration and Row Chaining Row Migration is caused when PCTFREE is set too low and there is not enough room in the block for updates. To avoid migration, all tables that are updated should have their PCTFREE set so that there is enough space within the block for updates. Row Chaining is caused when the row in a table is too large to fit into Oracle Data Block. To avoid Row Chaining the average row length has to be calculated and the table or cluster has to be created in the tablespace with corresponding block size. Detecting Row Migration and Row Chaining You can detect the existance of migrated and chained rows in a table or cluster by using the ANALYZE command with the COMPUTE Page 364

STATISTICS option. This command counts the number of migrated and chained rows and places this information in the CHAIN_CNT column of DBA_TABLES. The NUM_ROWS column provides the number of rows stored in the analyzed table or cluster. Compute the ratio of chained and migrated rows to the number of rows to decide if you need to eliminate migrated rows. You can also detect migrated and chained rows by checking the 'table fetch continued row' statistics in the V$SYSSTAT view. DEMO ON ROW CHAINING Create a table with low PCTFREE value SQL> create table migemp pctfree 5 as select * from emp; Table created. Inserting 10000 tuples into the emp table SQL> Insert into migemp select * from migemp; 1000 rows created. Commit complete. Modify one of the columns to a larger value SQL> Alter table emp modify ename varchar2(2000); Table altered. Analyze table to find the no.of rows, average row length, empty blocks, blocks used and the chain count from the data dictionary table dba_tables SQL> analyze table migemp compute statistics; Table analyzed. Page 365

Checking the details from the data dictionary view dba_tables especially check the chain_cnt column SQL> select table_name,avg_row_length,blocks,empty_blocks, chain_cnt from dba_tables where table_name='MIGEMP'; TABLE_NAME AVG_ROW_LEN BLOCKS EMPTY_BLOCKS CHAIN_CNT ------------------------------ ----------- ---------- ------------ ---------MIGEMP 41 234 55 0 Update the migemp table (ename column) with a value larger than the present value SQL> Update emp set ename='This is a test for checking Row Migration which is caused when PCTFREE is set to a low value' where empno=7566; 720 rows updated. Analyze table to find the no.of rows, average row length, empty blocks, blocks used and the chain count from the data dictionary table dba_tables SQL> analyze table migemp compute statistics; Table analyzed. Checking the details from the data dictionary view dba_tables especially check the chain_cnt column SQL> select table_name, avg_row_length, blocks, empty_blocks,chain_cnt from dba_tables where table_name='MIGEMP'; TABLE_NAME AVG_ROW_LEN BLOCKS EMPTY_BLOCKS CHAIN_CNT Page 366

------------------------------ ----------- ---------- ------------ ---------MIGEMP 47 279 10 480 To get the information about each migrated or chained row We need to create a specified output table CHAINED_ROWS which is created by using the script UTLCHAIN.SQL Utlchain.sql rem rem $Header: utlchain.sql 07-may-96.19:40:01 sbasu Exp $ rem Rem Copyright (c) 1990, 1995, 1996, 1998 by Oracle Corporation Rem NAME REM UTLCHAIN.SQL Rem FUNCTION Rem Creates the default table for storing the output of the Rem analyze list chained rows command Rem NOTES Rem MODIFIED Rem syeung 06/17/98 - add subpartition_name Rem mmonajje 05/21/96 - Replace timestamp col name with analyze_timestam Rem sbasu 05/07/96 - Remove echo setting Rem ssamu 08/14/95 - merge PTI with Objects Rem ssamu 07/24/95 - add field for partition name Rem glumpkin 10/19/92 - Renamed from CHAINROW.SQL Rem ggatlin 03/09/92 - add set echo on Rem rlim 04/29/91 - change char to varchar2 Rem Klein 01/10/91 - add owner name for chained rows Page 367

Rem Klein 12/04/90 - Creation Rem create table CHAINED_ROWS ( owner_name varchar2(30), table_name varchar2(30), cluster_name varchar2(30), partition_name varchar2(30), subpartition_name varchar2(30), head_rowid rowid, analyze_timestamp date ); SQL> @$ORACLE_HOME/rdbms/admin/utlchain.sql Table dropped. Table created. Name Null? Type ----------------------------------------- -------- ---------------------------OWNER_NAME VARCHAR2(30) TABLE_NAME VARCHAR2(30) CLUSTER_NAME VARCHAR2(30) PARTITION_NAME VARCHAR2(30) SUBPARTITION_NAME VARCHAR2(30) HEAD_ROWID ROWID ANALYZE_TIMESTAMP DATE Page 368

You can identify migrated and chained rows in a table or cluster by using the ANALYZE command with the LIST CHAINED ROWS option. This command collects information about each migrated or chained row and places this information into a specified output table. SQL> analyze table migemp list chained rows into chained_rows; Table analyzed. The rowid information of the chained or migrated rows are collected into CHAINED_ROWS table. You can query the no. of chained rows collected SQL> select count(head_rowid) from chained_rows where table_name='MIGEMP'; COUNT(HEAD_ROWID) ----------------480 Create a new table with the rows which aremigrated or chained in the table using the information in the CHAINED_ROWS table SQL> create table migbak as select * from migemp where rowid in (select head_rowid from chained_rows where table_name='MIGEMP'); Table created. Delete the chained rows from the table whichhas chained or migrated rows after creating a table that has chained rows SQL> delete migemp where rowid in (select head_rowid from chained_rows where table_name='MIGEMP'); 480 rows deleted. Insert all the rows back into the migemp table from the migbak table SQL> insert into migemp select * from migbak; Page 369

480 rows created. Analyze table to find the no.of rows, average row length, empty blocks, blocks used and the chain count from the data dictionary table dba_tables SQL> analyze table migemp compute statistics; Table analyzed. Checking the details from the data dictionary view dba_tables especially check the chain_cnt column SQL> select table_name,avg_row_length,blocks,empty_blocks, chain_cnt from dba_tables where table_name='MIGEMP'; TABLE_NAME AVG_ROW_LEN BLOCKS EMPTY_BLOCKS CHAIN_CNT ------------------------------ ----------- ---------- ------------ ---------MIGEMP 47 279 10 0 Drop the table which was used for swapping of chained or migrated rows from the original table SQL> drop table migbak; Table dropped. To prevent the table Row Migration for the future transactions increase the PCTFREE by a specific value SQL> alter table migemp pctfree 20; Table altered. Page 370

S-ar putea să vă placă și