Applyinga blockcentricapproach


Published on

oracle foreign key primary key constraints performance tuning MTS IOT 9i block size backup rman corrupted column drop rename recovery controlfile backup clone architecture database archives export dump dmp duplicate rows extents segments fragmentation hot cold blobs migration tablespace locally managed redo undo new features rollback ora-1555 shrink free space user password link TNS tnsnames.ora listener java shutdown sequence

  • Be the first to comment

  • Be the first to like this

No Downloads
Total Views
On Slideshare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Applyinga blockcentricapproach

  1. 1. Applying a Blockcentric Approach to Oracle TuningOverviewIn recent years Oracle tuning methodology has shifted away from ratios and percentages to waits and events.The new methods focus on the key component to user satisfaction, response time. By determining elapsed timefor each set of operations and identifying the bottlenecks, system performance can be improved, with acorresponding increase in user satisfaction.This paper presents a new method for application tuning that shifts the focus away from rows and towardsblocks. Simply stated, tune by reducing the number of blocks that a statement must read. It is built upon afoundation of solid research from the leaders (see references) in Oracle tuning and troubleshooting. Thepresentation is very high level and will not provide all the answers. In fact, the intent is to make you begin toask questions, and provide some guidance in finding the answers that are right for your database. “Trust, ButVerify.”Your current perceptions of tuning may be challenged. Be patient, kind reader, and all shall be made clear (Ihope). In the meantime, indulge my tuning heresy. “Burn him. Burn him at the stake. He speaks not the truth”Oracle’s I/O ModelThe cornerstone of the Blockcentric Approach is the Oracle I/O subsystem, how it reads and writes data. Mostof the work that the database does is the storage and retrieval of data. Lets set the foundation (of nice dry,burnable wood) for the approach.It’s The BlockWhen a query requests a single-byte column from a single row in a table, the block is read in its entirety. Inorder to make large read operations more efficient, Oracle can request multiple blocks from disk with a singleoperation. These multiblock reads are most often associated with full table scans, but are also used with fullindex scans. Full table scans read ALL blocks from the segment header up to the high water mark, the last blockever formatted to hold data.Logical ReadsA logical read is one where the block is already resident in memory. However, it is not as simple as looking upa memory address. The data block address must be determined and then hashed to a lookup value. Latches mustbe acquired, chains must be walked, additional latches allocated, if possible. If a read consistent version must becreated from undo, the undo block(s) must be read using the same process and the undo applied.Physical ReadsA physical read is where the block is not found in memory and must be requested from the storage subsystem.Many of the current disk storage systems do not always issue a disk read request for each block read request
  2. 2. that Oracle issues. Blocks may be stored in hardware caches or prefetched while Oracle is processing the blockand preparing the next request.Block SizesAs databases have grown, so have standard block sizes. Not too many versions ago, many databases used 2k fora block size. Now 8k is the defacto minimum, with some braving the waters of 32k. Larger block sizes maymean more data per block and a higher density of rows. This allows for more rows to be read with a single I/Orequest. While this has many benefits, it also has implications for tuning.MythconceptionsBuffer Cache Hit RatioThe higher the buffer cache hit ratio the better the statementThis Buffer Cache Hit Ratio (BCHR) has long been a keystone of the tuning foundation. Although manyperformance specialists regard this measure as something less than useful, it still persists among texts,documentation, papers and other sources. When faced with a less than optimal BCHR, the usual response was toincrease the block buffers. If the ratio was still not good enough, add more memory so you could increase theamount devoted to block buffers.Unfortunately, there is little correlation between this ratio and the user’s satisfaction with system performance.This ratio does not measure the response time. When faced with a slower than desired query, a user is rarelysatisfied with the response that it is "as good as it can be since the statement’s BCHR is 99.999%". In reality,this does not address the user issue.A statement with a lower BCHR may perform betterIf you compare two statements that return the same data and one has a higher BCHR, is this the betterperformer? Not necessarily! (“Burn him…”) The key is to compare the amount of resource that each statementconsumes, as measured by i/o operations, both logical and physical. By calculating the comparative costs, theless resource intensive one can be identified. In order to determine statement cost, we need to assign costs toeach of 2 components, logical i/os and physical i/os. Please note that we are not addressing either the parse norexecute phases of sql.Testing and research have shown that a read from memory is not nearly as expensive as has been accepted. Howcould this be? A logical i/o is not simply reading from disk, but it requires cpu processing, latch acquisition,consistent read generation, etc. A physical i/o does not necessarily require a disk read as the block may alreadyreside in the disk cache.In reality, physical I/O operations are only 40 times as expensive as logical I/Os, not 10,000 times as iscommonly accepted. Where does 40 come from? This is based upon data gathered and analyzed by Hotsos, The data is not tied to a particular Oracle release or server platform. Several independent sources havesimilar numbers, so the data can be presumed to be accurate.
  3. 3. The intent is not to provide a HERE IS THE MAGIC NUMBER solution, but rather a simple method forcalculating relative costs. There is a relatively simple formula for determining statement cost in terms of I/O. Statement_cost = logical_ios + (physical_ios * 40).Let’s apply this formula to two statements that return the exact same data. If the first statement has a 99%BCHR and does 6000 logical and 60 physical reads, while the second statement has a 75% BCHR and 400logical and 100 physical reads, the second statement will require less resource and should run faster. Tocalculate the cost of each statement, multiply the number of physical reads by 40 and add to the number oflogical reads. Using this method, the first statement will cost 8400 (6000 + (60*40)) while the second costs4400 (400 + (100*40)), thus indicating that the second statement is actually better performing.Identifying Tuning CandidatesThere are 2 ways to determine the statements most in need of tuning. You can wait until the line of disgruntledusers is beginning to form outside your cubicle or you can look at what is currently being executed in thedatabase. Many tuning tools will allow you to see the current sql statements with statistical information.V$SQLAREA contains the columns that will provide you the information you need. If you sort according to thesum of DISK_READS and BUFFER_GETS (in descending order), the most expensive statements will belisted first. In the example below, the first statement listed is consuming almost 20 times the resource as thesecond worst statement. Also notice that the top 4 most resource intensive statements have a 100% BufferCache Hit Ratio…all buffer gets and no disk reads!select address, substr(sql_text,1,50), disk_reads disk, buffer_gets buffer, executions execsfrom v$sqlareawhere (disk_reads + buffer_gets) > 100000order by (disk_reads+buffer_gets) desc;ADDRESS SUBSTR(SQL_TEXT,1,50) DISK BUFFER EXECS---------------- -------------------------------------------------- ----- -------- -------0000000387DFD0B0 DELETE FROM USER_INFORMATION_V WHERE CONNECTED_USE 0 99857399 8596800000003889FC7C0 DELETE FROM CONNECTED_SESSION WHERE ID = :1 0 5059551 43240000000384327720 DELETE FROM USER_INFORMATION_V WHERE CONNECTED_USE 0 5049585 432400000003855230D8 select count(1) from "VIRT"."USER_INFORMATION" whe 0 5020164 43240000000389C1A098 SELECT di.db_name from global_name gn, db_name 8 3012275 5018440000000387E59AE0 BEGIN CreateNewUserAndConnection_v3(:1, :2, :3, : 69 2825583 305500000000389816890 INSERT INTO ACTIVE_USER_V (ID, CON 50 2235420 305500000000387E3AFF0 UPDATE concurrent_users_v set running_co 22 1760499 331520000000389C62170 select count(*) from dual 4 945086 3150180000000389B22088 SELECT user_session_seq.NEXTVAL FROM DUAL 0 165386 54359Index UsageIf more than 15% of the rows are returned use an indexThis ratio has long been one of the most important considerations to create and use an index. If the number ofrows to be returned by the query was less than 15% (5% for parallel query), then it was ‘more efficient’ to usean index. This is a result of reading several index blocks to locate the requested value and the number of blocksthat can be read at a single time with multiple blocks.
  4. 4. The number of rows to be read is not a valid criteria , as Oracle does not read rows. The rows of interest couldbe clustered together, scattered amongst many blocks or have chained/migrated so that each row requiresseveral blocks to be read.The percentage of blocks read is the criteriaRemember, when a query retrieves rows, it reads blocks. If the same number of rows are clustered in a fewblocks or scattered amongst most of the blocks, different access paths are indicated. If the table is badlyfragmented with many empty blocks below the high water mark, index access paths may produce betterperforming statements. It may be better to use an index to return 100% of the rows and a full table scan to returnless than 1% of the rows. (“Sniff, sniff…is that burning wood I smell?”)The more telling criteria are the number of blocks to be returned. Ask the question, "How many blocks mustthis statement read in order to satisfy the query?" Answer the question in proportion to the number of blocks inthe table that are below the high water mark, not the number of blocks that contain data. There are three areasthat highlight this issue. The examples below are from a combination of tests, using a 1 million row table.Table Block FragmentationTable Block Fragmentation occurs when there are empty blocks in the table below the high watermark. Theusual culprits are massive deletes and failed transactions. When rows are deleted and blocks become emptythey are still allocated to the table so that they can be reused.If the table contains a large proportion of empty blocks below the high water mark, an index may be the bestchoice, even when all of the rows are to be returned by the query. If a full table scan is performed, many of theblocks read will be empty of data. An index lookup will only read those blocks that actually contain data. Retrieve 100% of the Rows using I/Os Full Table Scan 14,769 Using an Index 8,102As you can see from the above example, with a badly fragmented table, using an index instead of a full tablescan consumes 45% less I/O. The table had 1 million rows inserted, then all but 30,000 rows were deleted sothat all the contents of individual blocks were removed, leaving completely empty blocks while others werefilled with data.When a table has a high high watermark, the I/O savings are significantly higher. Even though a small fractionof the blocks actually contain data, the highwater mark is set as if the table contained 10 times the data. Retrieve 100% of the Rows using I/Os Full Table Scan 13,406 Using an Index 1,560In this example, the difference in I/O is very significant, with an Index read consuming almost 1/10 the amountof I/O that a Full Table Scan uses. This table had 1 million rows inserted and then all but 10,000 rows weredeleted. All the rows were in the blocks at the ‘beginning’ of the segment, in the same extent as the segmentheader.
  5. 5. Scattered DataIf the data of interest is scattered among a high proportion of the blocks, a full table scan may be a betterperforming access path even when a very small fraction of the rows are to be returned. One key factor toconsider is the density of the rows within blocks. For a very small row size with a large block size, scatteringbecomes more common. Retrieve 1% of the Rows using I/Os Using an Index 13,451 Full Table Scan 13,180In this example, the full table scan performed fewer I/Os. The I/O savings are not nearly as dramatic as theother examples, but it does indicate that the accepted rule of indexing does provide correct answers at all times.Because the data is scattered, all of the table blocks (and a significant number of index blocks) must be read.Clustered DataIf the data of interest is clustered, index scans may produce better results. Depending on the health of the index,an index may be more efficient with over 15% of the rows. Clustering can occur naturally, as in the case ofdaily sales records, or it may be artificial, as in the case of partitioned tables. Retrieve 7% of the Rows using an Index I/Os Data Scattered 7,282 Data Clustered 7,122 Data Partitioned (Scan of Partition) 3,751In this example, the clustering of data made a small (< 5%) improvement in the number of I/Os. Oracle providespartitioning as a method to enforce data clustering and enable the sql engine to take advantage of it. Here, thenumber of I/Os drops by almost 50% by scanning the table partition.Determining Block SelectivityTo determine the block selectivity for either a table or a data value, you need to determine how many blocks arebelow the high watermark and how many blocks are used by data. The tables must be analyzed and you must beable to execute the dbms_rowid package. In the user_table view, the column blocks indicates the number ofblocks below the high watermark. This is the number of blocks read by a full table scan.There is one condition that makes it very difficult to determine the block selectivity of individual data values. Ifa row is chained or migrated, the dbms_rowid package only reads the rowid of the head piece. If the value ofchain_cnt in the user_table view is high, it may cause the calculations to be incorrect.Identifying Table Block FragmentationFor each table, use the following query to determine the number of blocks containing data and those that arebelow the high watermark. Replace sequential_data with the table name that you want to examine. select count(dbms_rowid.rowid_block_number(s.rowid)), blocks from sequential_data s, user_tables
  6. 6. where table_name = SEQUENTIAL_DATA group by blocks;In the below example, the query was executed for 3 different tables. It indicates that a full table scan ofhwm_data will read 6483 blocks, while only 76 of the blocks actually contain data, while a full table scan ofsequential_data will access very few empty blocks. Table Blocks In Use Blocks below HWM % Of Used Blocks sequential_data 6348 6406 99% frag_data 1967 6483 30% hwm_data 76 6483 1%Identifying Block Selectivity for Data ValuesIn the past, indexing was based upon the % of Rows rule. However, this is not a reliable indicator as we haveseen. It is better to identify the number of blocks to be read for a given data value. Using the num_rows andblocks columns from the user_tables view, we can determine the block selectivity for a given value. In thestatement below, we are checking the block selectivity for the column small_random_num in thesequential_data table. select t.small_random_num data_value, count(t.small_random_num) data_rows, num_rows, round(((count(t.small_random_num)/num_rows)*100),2) pct_rows, count(distinct dbms_rowid.rowid_block_number(t.rowid)) data_blocks, blocks, round(((count(distinct dbms_rowid.rowid_block_number(t.rowid))/blocks)*100) ,2) pct_blocks from sequential_data t, user_tables where table_name = SEQUENTIAL_DATA group by blocks, num_rows, t.small_random_num;The query provides the following data, which indicates that there is a slight discrepancy between the row levelselectivity of a value and the block level selectivity. This indicates that the data value of 0 exists in almost 25%of the data blocks.DATA_VALUE DATA_ROWS NUM_ROWS PCT_ROWS DATA_BLOCKS BLOCKS PCT_BLOCKS---------- --------- -------- -------- ----------- ------ ---------- 0 152495 1000000 15.25 1564 6406 24.41 1 148751 1000000 14.88 1572 6406 24.54 2 147019 1000000 14.70 1584 6406 24.73 3 149802 1000000 14.98 1567 6406 24.46 4 132798 1000000 13.28 1396 6406 21.79 5 133659 1000000 13.37 1409 6406 22.00 6 135476 1000000 13.55 1424 6406 22.23If we execute the same query (modified for the new table) against the frag_data table, the results are quitedifferent. In this case, the data value of 0 exists in 5% of the blocks.DATA_VALUE DATA_ROWS NUM_ROWS PCT_ROWS DATA_BLOCKS BLOCKS PCT_BLOCKS---------- --------- -------- -------- ----------- ------ ----------
  7. 7. 0 4431 30480 14.54 322 6483 4.97 1 4410 30480 14.47 325 6483 5.01 2 4753 30480 15.59 350 6483 5.40 3 4755 30480 15.60 347 6483 5.35 4 3887 30480 12.75 284 6483 4.38 5 4105 30480 13.47 297 6483 4.58 6 4139 30480 13.58 291 6483 4.49Examining a different data value in the sequential_data table, where the data value is very, very scattered, theresults are quite dramatic. Even though the individual values (not all shown) compose an extremely smallpercentage of the rows, the value exists in almost every block in the table!DATA_VALUE DATA_ROWS NUM_ROWS PCT_ROWS DATA_BLOCKS BLOCKS PCT_BLOCKS---------- --------- -------- -------- ----------- ------ ---------- 0 6348 1000000 .63 6348 6406 99.09 1 6348 1000000 .63 6348 6406 99.09 2 6348 1000000 .63 6348 6406 99.09 3 6348 1000000 .63 6348 6406 99.09 4 6348 1000000 .63 6348 6406 99.09 5 6348 1000000 .63 6348 6406 99.09 6 6348 1000000 .63 6348 6406 99.09 7 6348 1000000 .63 6348 6406 99.09 8 6348 1000000 .63 6348 6406 99.09 9 6348 1000000 .63 6348 6406 99.09 10 6348 1000000 .63 6348 6406 99.09ConclusionI realize that I have presented no definitive answers to tuning and probably generated far more doubt andquestions. If I have, then I have succeeded. At some point, you have probably raised your eyebrows and said,“That is WRONG!” My response, “Prove it!” No, seriously, set up a test case, run it, send me the results. Ofcourse, if your test case proves me right, send it to me as well. Any and all information related to this approachwill help the Oracle community. I can be reached at and the ongoing results of theresearch will be posted at number of papers, presentations and books are too numerous to list individually. Instead, here is a list ofwebsites and 1 book that has provided valuable information and research. I am deeply indebted to the authorsfor their hard work that I have synthesized within this article.Oracle Performance Tuning 101 – Vaidyanatha, Deshpande & Kostelac. THE performance tuning manual.“Learn it, Know it, Live it.” - Cary Millsap’s website. His Oracle Internal’s presentation at IOUG-A Live 2002 providedme with the ‘Ah-Ha’ moment that inspired this - Tim Gorman’s site, with great contributions by Jeff Maresh. Excellent research, papers andpresentations.
  8. 8. - Craig Shallahamer’s site. Another of the gurus that consistently provide new ideas backedwith solid research.