Cookbook for Sizing Oracle Database Objects

Embed Size (px)

Citation preview

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    1/12

    Cookbook for Sizing Objects

    Had your fill of reading manuals and following cumbersome methods for sizingtables and indexes? Here's a recipe you'll find to your taste

    By James F. Koopmann

    I usually dread having to pull out pencil and paper and drill through software manuals to revisit the proper methods for sizing tables and indexes. Friends and colleagues have offered help in the way of spreadsheets and other methods, but I've always found these solutions a bit cumbersome and hard tomaintain when trying to update new information from analysts, developers, and users. And it was hardto change the data to reflect current trends for existing objects in the database.

    So I decided to automate this process to my own satisfaction. I created a couple of tables that I couldmaintain in an Oracle database that would give me the power to source in the volumetrics on theobjects in question. Essentially, it would give me information about the number of rows inserted intoan object, plus how the data in the object will grow or mutate over time. Keeping the information intables allows me to fully plan for current and future needs. Not only do I have at my fingertips thecurrent information about num_rows, pct_free, pct_used, and the like through the DBA tables but I canalso link in future growth patterns on the database. The ability to tie into the database where existingobjects reside is critical to fully understanding the current space needs of your database and predictingthe future ones.

    I have developed a recipe for setting up the tables in question, adding rows to those tables, and runninga couple of scripts that will get you started on reporting space requirements for your database.

    James F. Koopmann

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    2/12

    Select the Main course

    First of all, you need to capture all those little variables that Oracle maintains for its inner workings.The variables come from v$parameter and v$type_size tables and are all important in determining the

    overhead for each data block. The query in Listing 1 assumes a default of 1 for INITRANS and 20 for PCTFREE to show the working of the script. (I will use real values later in the article.) The query alsomakes extensive use of Oracle's ability to create dynamic views in the FROM clause of a SQLstatement. If you run the script in Listing 1, you should get output like that shown in Table 1.

    LISTING 1: newspace.sqlset linesize 132col db_block_size for a15

    select (a.db_block_size-b.kcbh-c.ub4-d.ktbbh-f.kdbh-((j.ini_trans-1)*e.ktbit)) hsize,

    CEIL((a.db_block_size-b.kcbh-c.ub4-d.ktbbh-f.kdbh-((j.ini_trans-1)*e.ktbit))*(1-j.pct_free/100))-g.kdbt availspace,

    a.db_block_size,b.kcbh,c.ub4,d.ktbbh,e.ktbit,f.kdbh,g.kdbt,h.ub1,i.sb2,j.ini_trans,j.pct_freefrom(select "NAME" ,"VALUE" db_block_size from v$parameter where name = 'db_block_size' ) a,(select "TYPE" ,"TYPE_SIZE" kcbh from v$TYPE_SIZE where "TYPE" = 'KCBH' ) b,(select "TYPE" ,"TYPE_SIZE" ub4 from v$TYPE_SIZE where "TYPE" = 'UB4' ) c,(select "TYPE" ,"TYPE_SIZE" ktbbh from v$TYPE_SIZE where "TYPE" = 'KTBBH') d,(select "TYPE" ,"TYPE_SIZE" ktbit from v$TYPE_SIZE where "TYPE" = 'KTBIT') e,(select "TYPE" ,"TYPE_SIZE" kdbh from v$TYPE_SIZE where "TYPE" = 'KDBH' ) f,(select decode(g.kdbt,0,c.ub4,g.kdbt) kdbt from

    (select "TYPE" ,"TYPE_SIZE" ub4 from v$TYPE_SIZE where "TYPE" = 'UB4' ) c,(select "TYPE" ,decode("TYPE_SIZE",NULL,0,"TYPE_SIZE") kdbt from v$TYPE_SIZE ,dual

    where "TYPE"(+) = 'KDBT' and dummy = "TYPE"(+) ) g ) g,(select "TYPE" ,"TYPE_SIZE" ub1 from v$TYPE_SIZE where "TYPE" = 'UB1' ) h,(select "TYPE" ,"TYPE_SIZE" sb2 from v$TYPE_SIZE where "TYPE" = 'SB2' ) i,(select 'INITRANS' ,1 ini_trans,

    'PCTFREE' ,20 pct_free from dual ) j/

    TABLE 1: Running the script in Listing1 should produce output similar to this.HSIZE AVAIL

    SPACEDR_BLOCK_ SIZE

    KCBH UB4 KTBBH KTBIT KDBH KDBT UB1 SB21 N1_TRANS PCT_ FREE

    8106 6481 8192 20 4 48 24 14 4 1 2 1 20

    The variables generated by the script are important, because they are used in virtually any script thatlooks at Oracle data blocks and measures how well they are being utilized. To check the utilization,you must know the current database block size (db_block_size); how much space is left after Oraclehas allocated header space (HSIZE); and, most important, how much of the block you can use to storedata (AVAILSPACE). The best part of this script is that it is independent of any machine and anydb_block_size. In past scripts, I hard-coded block_size. I have since substituted the hard-coded valueswith this script. One less thing to worry about!

    James F. Koopmann

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    3/12

    Prepare the PotatoesUse the statements in Listing 2 to create the sz_tables and sz_indexes tables to store sizing informationabout current or future tables and indexes. I have created the sz_tables and sz_indexes tables as asubset of the dba_tables and dba_indexes tables for two reasons: First, it allows me to run a set of

    space-estimation scripts against both the current statistics and the data in the DBA tables, as well asagainst future space requirements. I can then load that data into the sz_tables. Second, I wanted a wayto store information about objects that hadn't been created within the database and then still run thesame space-estimation scripts. To accomplish this, I just needed to load the sz_tables with datarepresentative of these future tables and indexes.To accomplish both of these things, the SQL makes extensive use of decodes, outer joins, and viewmaterialization to impose a form of logic for determining whether it should pull statistics fromsz_tables, dba_tables, or a combination of the two to calculate sizing requirements for the objects.

    LISTING 2: crtables.sql

    create table sz_tables(owner varchar2(30) not null,table_name varchar2(30) not null,tablespace_name varchar2(30),avg_row_len number default 1,ini_trans number default 1,pct_free number default 20,pct_used number default 80,num_rows number)TABLESPACE users/create table sz_indexes(owner varchar2(30) not null,index_name varchar2(30) not null,table_owner varchar2(30) not null,table_name varchar2(30) not null,tablespace_name varchar2(30),ini_trans number,pct_free number,index_entry_size number,uniqueness varchar2(9))TABLESPACE users/

    James F. Koopmann

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    4/12

    Add Some Salt, Maybe Some Pepper Getting data into the tables can be the most cumbersome task in this process. Typically, the tables andindexes are defined somewhere in a database or spreadsheet, or on paper. If the tables and indexes arealready in a database and the objects have been analyzed, you only have to do a couple of insert

    statements from the catalog and then modify the sizing tables for the future expectations. Insertingindex information can be tricky, because you have to sum the column lengths while accounting for thelengths of individual columns. Listing 3 does it for you.

    Inserting the table data in sz_tables is straightforward:insert into sz_tables (select owner,table_name,",avg_row_len,

    ini_trans,pct_free,pct_used,num_rowsfrom dba_tables where owner = '')

    If you are using information from users, data analysts, or your own researchand the objects are notdefined in a databaseloading the data can be more difficult. I suggest that you create a flat file withall the basic information, such as owner, table_name, and num_rows. Then create a small script to

    generate SQL statements from the flat file. The flat file might look something like this:Example : file.lst

    Table01 50 Table02 100000. . .. . . Table0n 13000

    A sample script for generating insert or update statements:# crszsql.shmore $1 | while read LINEdo

    OWNER='echo $LINE | awk '{print $1}' - | tr a-z A-Z'TABLE_NAME='echo $LINE | awk '{print $2}' - | tr a-z A-Z'NUM_ROWS='echo $LINE | awk "{print $3}"NEW_LINE="insert into sz_tables(owner,table_name,num_rows) \values ("$OWNER","$TABLE_NAME","$NUM_ROWS");'"echo $NEW_LINEdone

    You can pipe the output to another flat file, using: crszsql.sh file.lst > crszsql.sql

    Run this flat file in SQL*Plus to populate the sz_tables table. (This example is applicable only to

    UNIX installations. All other scripts, when in SQL*Plus, will work on any platform.) There are other,similar, ways to populate the sz_indexes table. It may seem cumbersome to create all the SQLstatements through a script, but if you manage more than one database or a couple of clients, you canlose sight of how or where you generated statements. This single point of creation from one flat file per database or client helps eliminate this problem. You can populate the tables any way you want: Theimportant thing is to get the initial object information into the tables.

    James F. Koopmann

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    5/12

    LISTING 3: Use the following script to insert the index information into your tables.insert into sz_indexes (select z0.owner,

    z0.index_name,z0.table_owner,z0.table_name,z0.tablespace_name,z0.ini_trans,z0.pct_free,sum(decode(sign(z1.column_length-126),1,z1.column_length+2,z1.column_length+1)),z0.uniqueness

    from dba_indexes z0, dba_ind_columns z1where z0.owner = z1.index_owner

    and z0.index_name = z1.index_nameand z0.table_owner = z1.table_ownerand z0.table_name = z1.table_nameand z0.owner not in ('SYS','SYSTEM')and z0.owner = '&owner'and z0.table_name like '&table_name%'

    group by z0.owner,z0.index_name,z0.table_owner,z0.table_name,z0.tablespace_name,z0.ini_trans,z0.pct_free,z0.uniqueness)

    /

    James F. Koopmann

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    6/12

    Bring to BoilI've also written a tblrowsz.sql script (Listing 4), which reports on estimated table sizes and generatestwo basic types of numbers Catalog numbers and Analyzed numbers. The Catalog numbers aregenerated from the dba_tables, whereas the Analyzed numbers are generated from a combination of

    dba_tables and the sz_tables table.

    This script prompts you to "Enter value for dba_tables:" which is where you specify dba_tables or sz_tables. If you enter dba_tables, the report will compare sizing estimates based entirely on data keptin the current catalog. If you enter sz_tables, the report will calculate sizing estimates based on both thedba_tables and sz_tables. You will also be prompted to enter a value for table_name that specifies atable name or pattern on which to report. Press Enter for the default (which shows all tables), or type ina pattern on which to search.Use Table 6 at the end of this paper to help determine the output of the report and from where the datais derived. Data must exist in the sz_tables table; otherwise, it won't generate a report. The output fromtblrowsz.sql looks like that shown in Table 4.

    TABLE 4: Sample output from the tblrowsz.sql script.Owner Table

    NameCatalogRowsize

    CatalogRowsperBlock

    AnalyzedRowsize

    AnalyzedRowsperBlock

    AnalyzedNumberof Rows

    AnalyzedBlocksNeeded

    AnalyzedSpaceNeeded(Meg)

    CatalogSpaceNeeded(Meg)

    PctFree

    Pct_ Used

    87 83 61 119 15963 134 1 1 10 60 841 7 267 24 1958100 81587 637 2185 20 60 1060 6 425 15 4220403 281360 2198 5495 20 40 264 27 139 52 46322 890 6 13 10 60 76 95 71 102 44200 433 3 3 10 60

    There you have it: a script that can do sizing for tables with data from the analyzed data in dba_tablesor your own sizing table in sz_tables. The Catalog Space Needed amount typically exceeds that for Analyzed Space Needed , because full column sizes are used from the dba_tab_columns in thecalculation of the catalog space. This calculation is useful because if all else stays the same, this is thelargest amount of space you will need. You can run this script from dba_tables to report current spacerequirements and then run it from sz_tables to see future requirements, take the difference, anddetermine whether you have enough space to extend the tablespace.

    James F. Koopmann

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    7/12

    LISTING 4: tblrowsz.sqlcol owner for a09 head 'Owner'col table_name for a30 head 'Table Name'col cat_rowsize for 99999 head 'Catalog|Rowsize'col cat_rows_per_block for 999999 head 'Catalog|Rows|per|Block'col anl_rowsize for 99999 head 'Analyzed|Rowsize'

    col anl_rows_per_block for 999999 head 'Analyzed|Rows|per|Block'col anl_num_rows for 999999999 head 'Analyzed|Number|of Rows'col anl_blocks for 999999 head 'Analyzed|Blocks|Needed'col anl_space for 999999 head 'Analyzed|Space|Needed|(Meg)'col cat_space for 999999 head 'Catalog|Space|Needed|(Meg)'col tbl_pct_free for 999 head 'Pct|Free'col tbl_pct_used for 999 head 'Pct|Used'select y.owner, y.table_name,

    (3*z.ub1)+y.rowsize cat_rowsize,decode(FLOOR(availspace/((3*z.ub1)+y.rowsize)),0,1,

    (FLOOR(availspace/((3*z.ub1)+y.rowsize)))) cat_rows_per_block,(3*z.ub1)+avg_row_len anl_rowsize,decode(FLOOR(availspace/((3*z.ub1)+avg_row_len)),0,1,

    (FLOOR(availspace/((3*z.ub1)+avg_row_len)))) anl_rows_per_block,num_rows anl_num_rows,FLOOR(num_rows/

    (decode(FLOOR(availspace/((3*z.ub1)+avg_row_len)),0,1,

    (FLOOR(availspace/((3*z.ub1)+avg_row_len)))))) anl_blocks,FLOOR((db_block_size*FLOOR(num_rows/(decode(FLOOR(availspace/((3*z.ub1)+avg_row_len)),0,1,(FLOOR(availspace/((3*z.ub1)+avg_row_len)))))))/1024/1024) anl_space,

    FLOOR((db_block_size*FLOOR(num_rows/(decode(FLOOR(availspace/((3*z.ub1)+((3*z.ub1)+y.rowsize))),0,1,(FLOOR(availspace/((3*z.ub1)+((3*z.ub1)+y.rowsize))))) )))/1024/1024) cat_space,

    tbl_pct_free,tbl_pct_used

    from(select owner,table_name,sum(decode(sign(data_length-249),1,data_length+3,data_length+1)) rowsizefrom sys.dba_tab_columns zz

    group by owner,table_name) y,(select j.owner owner,

    j.table_name table_name,j.avg_row_len avg_row_len,j.num_rows num_rows,j.pct_free tbl_pct_free,

    j.pct_used tbl_pct_used,(a.db_block_size - b.kcbh - c.ub4 - d.ktbbh - f.kdbh - ((ini_trans-1)*e.ktbit)) hsize,CEIL((a.db_block_size - b.kcbh - c.ub4 - d.ktbbh - f.kdbh - ((ini_trans-1)*e.ktbit)) *( 1 - pct_free / 100 )) - g.kdbt availspace,

    a.db_block_size,b.kcbh,c.ub4,d.ktbbh,e.ktbit,f.kdbh,g.kdbt,h.ub1,i.sb2,ini_trans,pct_free from(select "NAME" ,"VALUE" db_block_size from v$parameter where name = 'db_block_size') a,(select "TYPE" ,"TYPE_SIZE" kcbh from v$TYPE_SIZE where "TYPE" = 'KCBH' ) b,(select "TYPE" ,"TYPE_SIZE" ub4 from v$TYPE_SIZE where "TYPE" = 'UB4' ) c,(select "TYPE" ,"TYPE_SIZE" ktbbh from v$TYPE_SIZE where "TYPE" = 'KTBBH') d,(select "TYPE" ,"TYPE_SIZE" ktbit from v$TYPE_SIZE where "TYPE" = 'KTBIT') e,(select "TYPE" ,"TYPE_SIZE" kdbh from v$TYPE_SIZE where "TYPE" = 'KDBH' ) f,(select decode(gg.kdbt,0,c.ub4,gg.kdbt) kdbt from

    (select "TYPE" ,"TYPE_SIZE" ub4 from v$TYPE_SIZE where "TYPE" = 'UB4' ) c,(select "TYPE" ,decode("TYPE_SIZE",NULL,0,"TYPE_SIZE") kdbt from v$TYPE_SIZE ,dual

    where "TYPE"(+) = 'KDBT' and dummy = "TYPE"(+) ) gg ) g,(select "TYPE" ,"TYPE_SIZE" ub1 from v$TYPE_SIZE where "TYPE" = 'UB1' ) h,(select "TYPE" ,"TYPE_SIZE" sb2 from v$TYPE_SIZE where "TYPE" = 'SB2' ) i,(select owner, table_name, AVG_ROW_LEN avg_row_len,

    INI_TRANS ini_trans, PCT_FREE pct_free, PCT_USED pct_used, NUM_ROWS num_rowsfrom &dba_tables jj where jj.table_name like upper('&table_name%') ) j ) z

    where y.owner(+) = z.ownerand y.table_name(+) = z.table_name

    /undef table_nameundef dba_tables

    James F. Koopmann

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    8/12

    Let Simmer The next script, ixrowsz.sql (Listing 5), calculates index sizes. This script also generates two types of numbers in its report: Catalog numbers and Sizing numbers. The Catalog numbers are generated fromdba_tables, and the Sizing numbers are generated from a combination of sz_tables and dba_tables. Thescript will prompt you to "Enter value for dba_indexes:" which is where you enter dba_indexes or

    sz_indexes. If you specify dba_indexes, the report will be driven from the dba_indexes table. Anytables that also exist on the sz_indexes table will also be reported. If you specify sz_indexes, the reportwill be driven off the sz_indexes table. If any of the same indexes are defined in the catalog, they willalso be reported.Be aware, if you want to use the sz_indexes table, that the script uses the sz_tables table to determinethe number of rows for the table on which the index resides. To obtain sizing estimates on indexes, youmust have an entry in both the sz_tables table and the sz_indexes table.Use the information in Table 7 to view your calculated index sizes and to see the source from whichthe data is collected (assuming you've entered data in sz_tables). You will also be prompted to enter avalue for index_name, for which you can press the Enter key (to get the default of all tables) or enter aindex name or pattern on which to search.

    The output from ixrowsz.sql will be similar to that shown in Table 5. There's nothing fancy about thereport: It shows current and future size estimates on the same line of a report so you can plan for growth.

    TABLE 5: Sample output from ixrowsz.sql.Owner Index

    NameCatalogIndexEntrySize

    CatalogBlocksforIndex

    CatalogNumberof Rows

    CatalogSpaceNeeded(Meg)

    SizingIndexEntrySize

    SizingBlocksforIndex

    SizingNumberof Rows

    SizingSpaceNeeded(Meg)

    19 11649 4220403 91 19 17473 6330605 137 37 10529 1958850 82 37 15787 2937150 123

    28 197 48442 2 28 283 69483 2 19 11649 4220403 91 29 26670 6330605 208 37 10529 1958850 82 66 28161 2937150 220 28 197 48442 2 48 485 69483 4

    James F. Koopmann

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    9/12

    LISTING 5: ixrowsz.sqlcol owner for a15 head 'Owner'col index_name for a30 head 'Index Name'col cat_index_entry_size for 9999990 head 'Catalog|Index|Entry|Size'col cat_blocks for 99999990 head 'Catalog|Blocks|for|Index'col cat_num_rows for 999999999 head 'Catalog|Number|of Rows'

    col cat_space for 9999990 head 'Catalog|Space|Needed|(Meg)'col sz_index_entry_size for 9999990 head 'Sizing|Index|Entry|Size'col sz_blocks for 99999990 head 'Sizing|Blocks|for|Index'col sz_num_rows for 999999990 head 'Sizing|Number|of Rows'col sz_space for 9999990 head 'Sizing|Space|Needed|(Meg)'select y.owner,y.index_name,

    decode(y.uniqueness,'NONUNIQUE',1,0)+2+6+y.dba_index_entry_size cat_index_entry_size,1.05*((num_rows*(decode(y.uniqueness,'NONUNIQUE',1,0)+2+6+y.dba_index_entry_size)) /

    (availspace)) cat_blocks,num_rows cat_num_rows,(1.05*((num_rows*(decode(y.uniqueness,'NONUNIQUE',1,0)+2+6+y.dba_index_entry_size)) /

    (availspace)))*db_block_size/1024/1024 cat_space,decode(y.uniqueness,'NONUNIQUE',1,0)+2+6+y.sz_index_entry_size sz_index_entry_size,1.05*((sz_num_rows*(decode(y.uniqueness,'NONUNIQUE',1,0)+2+6+y.sz_index_entry_size)) /

    (availspace)) sz_blocks,sz_num_rows sz_num_rows,(1.05*((sz_num_rows*(decode(y.uniqueness,'NONUNIQUE',1,0)+2+6+y.sz_index_entry_size)) /

    (availspace)))*db_block_size/1024/1024 sz_spacefrom(select z0.owner,z0.index_name,

    sum(decode(sign(column_length-126),1,column_length+2,column_length+1)) dba_index_entry_size,z2.index_entry_size sz_index_entry_size,z0.uniqueness

    from &&dba_indexes z0, dba_ind_columns z1, sz_indexes z2where z0.owner = z1.index_owner(+) and z0.index_name = z1.index_name(+)

    and z0.table_owner = z1.table_owner(+) and z0.table_name = z1.table_name(+)and z0.owner = z2.owner(+) and z0.index_name = z2.index_name(+)and z0.table_owner = z2.table_owner(+) and z0.table_name = z2.table_name(+)

    group by z0.owner,z0.index_name,z0.uniqueness,z2.index_entry_size) y,(select j.owner, j.index_name, j.num_rows, j.sz_num_rows,(a.db_block_size - j.block_header) -

    ((a.db_block_size - j.block_header)*(pct_free/100)) availspace,a.db_block_size,b.kcbh,c.ub4,d.ktbbh,e.ktbit,f.kdbh,g.kdbt,h.ub1,i.sb2,j.ini_trans,j.pct_free

    from(select "NAME" ,"VALUE" db_block_size from v$parameter where name = 'db_block_size' ) a,

    (select "TYPE" ,"TYPE_SIZE" kcbh from v$TYPE_SIZE where "TYPE" = 'KCBH' ) b,(select "TYPE" ,"TYPE_SIZE" ub4 from v$TYPE_SIZE where "TYPE" = 'UB4' ) c,(select "TYPE" ,"TYPE_SIZE" ktbbh from v$TYPE_SIZE where "TYPE" = 'KTBBH') d,(select "TYPE" ,"TYPE_SIZE" ktbit from v$TYPE_SIZE where "TYPE" = 'KTBIT') e,(select "TYPE" ,"TYPE_SIZE" kdbh from v$TYPE_SIZE where "TYPE" = 'KDBH' ) f,(select decode(g.kdbt,0,c.ub4,g.kdbt) kdbt from

    (select "TYPE" ,"TYPE_SIZE" ub4 from v$TYPE_SIZE where "TYPE" = 'UB4' ) c,(select "TYPE" ,decode("TYPE_SIZE",NULL,0,"TYPE_SIZE") kdbt from v$TYPE_SIZE ,dual

    where "TYPE"(+) = 'KDBT' and dummy = "TYPE"(+) ) g ) g,(select "TYPE" ,"TYPE_SIZE" ub1 from v$TYPE_SIZE where "TYPE" = 'UB1' ) h,(select "TYPE" ,"TYPE_SIZE" sb2 from v$TYPE_SIZE where "TYPE" = 'SB2' ) i,(select j0.owner,j0.index_name, (113+(24*j0.INI_TRANS)) block_header,

    j0.INI_TRANS ini_trans, j0.PCT_FREE pct_free,j1.NUM_ROWS num_rows, j2.NUM_ROWS sz_num_rows

    from &&dba_indexes j0, dba_tables j1, sz_tables j2where j0.index_name like upper('&index_name%')

    and j0.table_owner = j1.owner(+) and j0.table_name = j1.table_name(+)and j0.table_owner = j2.owner(+) and j0.table_name = j2.table_name(+)

    ) j ) zwhere y.owner = z.owner

    and y.index_name = z.index_nameorder by y.owner,y.index_name

    /undef index_nameundef dba_indexesundef dba_tables

    James F. Koopmann

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    10/12

    Serve and EnjoyOracle has removed many of the barriers and headaches associated with sizing and managing objects ina database, but you still must consider size when creating new objects, in order to avoid performanceand maintenance problems.

    This recipe covers just the basics, but it should be enough to get you started in automating the processof sizing database objects. Remember, there is much more to it than just selecting an initial_extent anda next_extent: You truly have to know your data and watch it grow over a given period of time todetermine if the pctfree, pctused, ini_trans, and next_extent are set properly to facilitate growthwithout having a negative impact on performance.

    Start capturing growth patterns in another set of tables. Key tables to mirror and monitor aredba_tables, dba_tablespaces, and dba_segments. If you do this, you will gain a wealth of informationon growth patternsor lack of growthwithin your database within two or three weeks.You might want to start running a couple of scripts, such as blkixchk.sql, that I introduced in theMarch/April 1997 issue of Oracle Magazine to monitor block usage for indexes and tables. (See

    www.oramag.com for an archive of articles from past issues.)

    If you're interested in further reading on the performance aspects of sizing objects, check out thefollowing books and papers:

    Space Estimations for Schema Objects, Appendix A, Oracle Server Administrator's Guide Release 8.0; Oracle Corporation, 1997.

    The following are available through OraPub of Earth at www.europa.com/~orapub :

    Millsap, Cary V.Oracle7 Server Space Management, Revision 1.4b (10/31/95) Shallahamer, Craig A.Avoiding a Database Reorganization (11/2/94) V2.2

    James F. Koopmann

    http://www.oramag.com/http://www.europa.com/~orapubhttp://www.europa.com/~orapubhttp://www.oramag.com/http://www.europa.com/~orapub
  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    11/12

    TABLE 6: Use the information in this table to select a response for the "Enter value for dba_tables:" prompt.

    Column dba_indexes sz_indexes

    CatalogRowsize

    The sum of column lengths fromdba_tab_columns

    Same as for dba_tables if table exists in catalog

    Catalog Rows per Block

    The number of rows, given the catalogrowsize, that will fit into a block

    Same as for dba_tables if table exists in catalog

    AnalyzedRowsize

    The avg_row_len from dba_tables after ananalyze has been done on the table

    The avg_row_len from sz_tables

    Analyzed Rows per block

    The number of rows, given the analyzedavg_row_len, that will fit into a block

    The number of rows, given the avg_row_len fromsz_tables, that will fit into a block

    Analyzed Number of Rows

    The value of num_rows from dba_tablesafter an analyze has been done on the table

    The num_rows from sz_tables

    AnalyzedBlocks

    Needed

    The number of data blocks needed, giventhe analyzed rows per block and analyzednumber of rows

    The number of data blocks needed, given the rows per block and the number of rows from the sz_tables data

    AnalyzedSpace Needed(megabytes)

    Total space needed, determined bydba_block_size, dba_tables, and analyzed

    blocks needed

    Total space needed, determined by dba_block_size,sz_tables, and analyzed blocks needed

    CatalogSpace Needed(megabytes)

    Total space needed determined by catalog blocks needed (not in report)and analyzed num_rows from dba_tables

    Total space needed determined by catalog blocksneeded (not in report) and num_rows from sz_tables

    Pct Free The percentage free from dba_tables The percentage free from sz_tables

    Pct Used The percentage used from dba_tables The percentage used from sz_tables

    James F. Koopmann

  • 8/6/2019 Cookbook for Sizing Oracle Database Objects

    12/12

    TABLE 7: Use the following to select the information to answer the "Enter value for dba_indexes:" prompt.

    Column dba_indexes sz_indexes

    Catalog IndexEntry Size

    The sum of column lengthsfrom dba_ind_columns

    Same as for dba_indexes, if index exists in the catalog

    Catalog Blocksfor Index

    The computed number of blocks to hold index, giventhe catalog index-entry size,num_rows from dba_tables,and available space

    per block

    Same as for dba_indexes, if index exists in the catalog

    Catalog Number of Rows

    The value of num_rowsfrom dba_tables

    Same as for dba_indexes, if index exists in the catalog

    Catalog Space Needed(megabytes)

    The calaculated space giventhe cataloged blocks for index and available space

    per block

    Same as for dba_indexes, if index exists in the catalog

    Sizing IndexEntry Size

    Same as sz_indexes, if entryin sz_indexes exists

    Index_entry_size fromsz_indexes

    Sizing Blocksfor Index

    Same as sz_indexes, if entryin sz_indexes exists

    Computed number of blocks to hold index, giventhe sizing index entry size,num_rows from sz_tables,and available space

    per block

    Sizing Number of Rows

    Same as sz_indexes, if entry in sz_indexes exists

    The value of num_rowsfrom sz_tables

    Sizing Space Needed(megabytes)

    Same as sz_indexes, if entry in sz_indexes exists

    The calculated space, giventhe sizing blocks for indexand available space

    per block

    James F. Koopmann