Oracle Performance Tune Plan
上一篇 / 下一篇 2008-01-03 00:00:00 / 个人分类:数据库专区
Objective
The objective of this document is to provide the simplified steps for Oracle performance tune of application system development.
And the document doesn’t involve performance tune of OS, Database parameter, and database physical and logical Structure.
Keywords
Performance tune, Scalability
INTRODUCTION
This document is prepared on the basis of my project experience for Oracle Performance tune and coding standard.
Following is the step of Oracle performance tune plan:
1.Establish the Oracle naming and Code standard.
2.make sure the synchronization between the E-R model and DB schema
3.When finish the first two steps, and the job will succeed half.
4.Building the index script. based on the DB foreign key and the selection of the fields.
5.Building the index script. based on java property file.
6.Building the index script. based on java dynamic SQL.
7.provide the estimation of table data volume and table type for customer and we can focus on the frequent transaction and large table to make performance tune
8.When create the index script. and the task has finish 90%.
9.Check the DB performance view and find the Top N SQL consumed with high CPU, Memory and I/O.
Oracle Naming and Coding Standard
- Use full, descriptive, pronounceable names (or well-known abbreviations).
- Use consistent naming rules.
- Use the same name to describe the same entity or attribute across tables.
- All the entity and object Names must be from 1 to 30 bytes
- Nonquoted identifiers are not case sensitive. Oracle interprets them as uppercase. Quoted identifiers are case sensitive. So never use the oracle reserved key word.
- Nonquoted identifiers must begin with an alphabetic character from your database character set.
- Never use SQL like“SELECT * FROM tablename”
- When coding, all the oracle reserved key word should be upper.
STEP1. Check table naming standard
v$reserved_words comprise all the oracle reserved key word, but not all the reserved word can’t be used as table name or column name. Only some restricted key word can’t be used. Table name should not blank character.
SELECT * FROM user_tables WHERE table_name IN --(SELECT keyword FROM v$reserved_words) ( Or table_name LIKE ‘% %’ |
STEP2. Check column naming standard
The rule is same with table name
Select TABLE_NAME,COLUMN_NAME,DATA_TYPEITPUB个人空间^4Up"H&m:p0F (ITPUB个人空间-Q!_HfM Or column_name Like '% %' |
STEP3. Check the same columns have same data type
Use the same name to describe the same entity or attribute across tables, if the data type is not uniform, when join query, it will bring out the bad performance and wrong business logic.
SELECT a.column_name,a.data_type,b.data_type FROM (SELECT distinct column_name,data_type FROM all_tab_columns WHERE TABLE_NAME LIKE 'T%') a, (SELECT distinct column_name,data_type FROM all_tab_columns WHERE TABLE_NAME LIKE 'T%') b WHERE a.column_name=b.column_name AND a.data_type<>b.data_type |
STEP4. Check the same columns have same data type and same data length
It hasn’t too much infect, sometimes it will bring out confused.
SELECT a.column_name,a.data_type,b.data_type,a.data_length,b.data_length FROM (SELECT DISTINCT column_name,data_type,data_length FROM all_tab_columns WHERE TABLE_NAME LIKE 'T%') a, (SELECT DISTINCT column_name,data_type,data_length FROM all_tab_columns WHERE TABLE_NAME LIKE 'T%') b WHERE a.column_name=b.column_name AND a.data_type=b.data_type AND a.data_length<>b.data_length |
Make sure synchronization between E-R model and DB schemaIn theory, the E-R model should be synchronize with DB schema, when we modified the E-R model, we should create the upgrade script-modified SQL syntax, but sometimes when the requirement change is very big and the modification is very large, the E-R model is out of joint with DB schema. How we make sure the synchronization?STEP1.We should create a full SQL script, and then reduce the redundancy, later create a new tablespace, execute the SQL script, and then we get a latest DB environment.STEP2.Create a DB link like REMOTEXXX, when two DB not in the same instance.Grant the old environment privilege to new user, then use the schema’s name.STEP3.Compare the new table or dropped table with old environment.
--Check the tables in ER-Model, but not in development or old environment. Then get the create table script, but not include index, foreign key and primary key constraint.SELECT sqlText FROM(SELECT 'CREATE TABLE '||table_name AS sqlText,-1 AS column_ID,table_nameFROM user_tablesUNIONSELECT '(' AS sqlText,0 AS column_ID,table_nameFROM user_tablesUNIONSELECT ');' AS sqlText,100 AS column_ID,table_nameFROM user_tablesUNIONSELECTCASE WHEN DATA_TYPE='NUMBER'THENCASE WHEN DATA_PRECISION IS NULLTHEN COLUMN_NAME||' INTEGER,'ELSE COLUMN_NAME||' '||DATA_TYPE||'('||TO_CHAR(DATA_PRECISION)||','||TO_CHAR(DATA_SCALE)||')'||DECODE(column_ID,(SELECT MAX(B.column_ID) FROM user_tab_columns B WHERE A.table_name=B.table_name),' ',',')ENDWHEN DATA_TYPE='NVARCHAR2'THEN COLUMN_NAME||' '||DATA_TYPE||'('||TO_CHAR(DATA_LENGTH/2)||')'||DECODE(column_ID,(SELECT MAX(B.column_ID) FROM user_tab_columns B WHERE A.table_name=B.table_name),' ',',')WHEN DATA_TYPE IN ('CHAR','VARCHAR2')THEN COLUMN_NAME||' '||DATA_TYPE||'('||TO_CHAR(DATA_LENGTH)||')'||DECODE(column_ID,(SELECT MAX(B.column_ID) FROM user_tab_columns B WHERE A.table_name=B.table_name),' ',',')WHEN DATA_TYPE IN ('DATE','BLOB','CLOB','LONG','NCLOB')THEN COLUMN_NAME||' '||DATA_TYPE||DECODE(column_ID,(SELECT MAX(B.column_ID) FROM user_tab_columns B WHERE A.table_name=B.table_name),' ',',')END AS sqlText,column_ID,A.table_nameFROM user_tab_columns AWHERE A.table_name Like 'T%') dWHERE d.table_name Not In(SELECT c.table_nameFrom user_tables@REMOTEXXX cWHERE c.table_name LIKE'T%')ORDER BY table_name,column_ID,sqlText
|
STEP4.Compare the different fields between E-R model and old environment.
--Check the fields in E-R model and not in old environment and create ‘ALTER TABLE XXX ADD XXX’ script.SELECT 'ALTER TABLE '||TABLE_NAME||' ADD "'||COLUMN_NAME||'" '||(CASE WHEN DATA_TYPE='NUMBER'THENCASE WHEN DATA_PRECISION IS NULLTHEN 'INTEGER'ELSE DATA_TYPE||'('||TO_CHAR(DATA_PRECISION)||','||TO_CHAR(DATA_SCALE)||')'ENDWHEN DATA_TYPE='NVARCHAR2'THEN DATA_TYPE||'('||TO_CHAR(DATA_LENGTH/2)||')'WHEN DATA_TYPE IN ('CHAR','VARCHAR2')THEN DATA_TYPE||'('||TO_CHAR(DATA_LENGTH)||')'WHEN DATA_TYPE IN ('DATE','BLOB','CLOB','LONG','NCLOB')THEN DATA_TYPEEND)||' ;' SQLTEXTFROM USER_TAB_COLUMNS AWhere (a.table_name,a.column_name) Not In(Select b.table_name,b.column_name From test_remote bWhere b.table_name Like 'T%')And A.table_name Like 'T%'ORDER BY COLUMN_ID
|
Build index based on foreign key constraintA foreign key constraint (also called a referential integrity constraint) designates a column as the foreign key and establishes a relationship between that foreign key and a specified primary or unique key, called the referenced key.In fact, any operation on parent table will impact the child table, like update, delete, insert, usually they are queried together; we get the detail information from parent table.The sentence is reference from Oracle Official DocumentJust as the index in this manual helps you locate information faster than if there were no index, an Oracle index provides a faster access path to table data. Indexes are the primary means of reducing disk I/O when properly used.So we must find all the foreign key constraint and foreign key fields and find some high-selection field to build index.STEP1.Create a new function to get the constraint field name, Oracle use user_cons_columns and user_constraints to storage the constraint information, sometimes the constraint comprise one more than fields. The function is used to get all the constraint fields combined with ‘,’.
CREATE OR REPLACE FUNCTION f_GetConstraintColumn(itablename IN VARCHAR2,iConstraintName IN VARCHAR2)RETURN VARCHAR2 ISTYPE cur_type is REF CURSOR;myCur cur_type;v_Column1Value VARCHAR2(4000);v_Result VARCHAR2(32767);beginOPEN myCur FOR SELECT column_nameFROM user_cons_columnsWHERE table_name=itablename AND constraint_name=iConstraintNameORDER BY POSITION;LOOPFetch myCur Into v_Column1Value;Exit When myCur%notfound;v_Result:=v_Result||v_Column1Value||',';End Loop;Close myCur;v_Result:=substr(v_Result,1,length(v_Result)-1);return(v_Result);END; |
STEP2.Get the entire distinct field name. then we judge the fields by manual, and find which field is more fit for building index, we choose the high –selection fields.
SELECTDISTINCT f_GetConstraintColumn(a.table_name, a.constraint_name) ForeignKeyColumnsNameFROM user_constraints a,user_constraints bWHERE a.constraint_type='R'AND a.r_constraint_name=b.constraint_nameAND a.table_name Like 'T%'ORDER BY a.table_name, a.constraint_name |
STEP3.According the high-selection fields, we can build out index script.
SELECTa.table_name ForeignKeyTableName, a.constraint_name,f_GetConstraintColumn(a.table_name, a.constraint_name) ForeignKeyColumnsName,a.r_constraint_name,b.table_name PrimaryKeyTableName,f_GetConstraintColumn(b.table_name, a.r_constraint_name) PrimaryKeyColumnsName,'Create index '||replace(a.constraint_name,'FK','IDX')||' on '||a.table_name||'('||f_GetConstraintColumn(a.table_name, a.constraint_name)||');' indexSQLFROM user_constraints a,user_constraints bWHERE a.constraint_type='R'AND a.r_constraint_name=b.constraint_nameAND a.table_name Like 'T%'AND f_GetConstraintColumn(a.table_name, a.constraint_name) In('INV_ID','ISSUE_ID','MELT_ID','MELT_SUM_ID','MIX_ID','PRICING_ID','PROD_ORDER_ID','PROD_ORDER','REF_INV_ID','SETT_ID','STYLE_ID','VOU_ID','WIP_ISSUE_DET_ID','WIP_ISSUE_ID','WIP_RET_ID','METAL_LOT_CODE','SCHEDULE_ID','MELT_CONT_ID','APP_INV_DET_ID','ORDER_DET_ID','STYLE_STONE_CARD_ID','MLD_ISSUE_DET_ID','CUS_ID,FAC_COMP_ID','T_WIP_ISSUE_ID','FG_STOCK_ID','PO_ID','LOT_CODE','INV_ID','NEW_CONT_ID','SET_ID','SCAN_ID','WIP_ISSUE_ID','MENU','PN_ID','STYLE_ID','DES_ID','VOU_ID','FAC_INV_ID','REP_CONT_ID','DEMD_DET_ID')ORDER BY a.table_name, a.constraint_name |
Build index based on java property fileInjavaapplication, developer use the property file to encapsulate SQL syntax. The format in property file is like this:XXX_SELECT=SELECTID, DT FROMT_XXXWHEREIS_DELETED='N'So we need to parse the every entry, and divide into Operation type, Table part, where clause part, then we analyze the table and where to make decision how to create index, base on operation type, we can’t concern on the insert SQL and dual table.STEP1.Create analyze table, the table storage the different SQL part.
create table XXX_PROPERTY_SQL(SQLMODULEVARCHAR2(100),SQLTAGVARCHAR2(100),SQLCONTENTVARCHAR2(3000),SQLTABLEVARCHAR2(200),SQLWHEREVARCHAR2(3000),SQLORIGINAL VARCHAR2(3000),OPERATETYPE VARCHAR2(30))--create a temporary table like XXX_PROPERTY_SQL |
STEP2.Load the property SQL file into the SQLOriginal field of XXX_property_sql_temp table, first we format the property file, then through PL/SQL development tool, copy into the fields and save it into DB.STEP3.Delete the unfit SQL, like remark line and NULL line, and other line.
delete from XXX_property_sql_temp where sqloriginal like '#%' or sqloriginal is null;commit; |
STEP4.Change the sqlmodule name
Update XXX_property_sql_tempSet sqlmodule=&isqlmodule;commit; |
STEP5.Change the sqltag name, get the sentence before ‘=’
Update XXX_property_sql_tempSet sqltag=substr(sqloriginal,1,instr(sqloriginal,'=')-1);commit; |
STEP6.Change the sqlcontent name, get the sentence after ‘=’
Update XXX_property_sql_tempSet sqlcontent=substr(sqloriginal,instr(sqloriginal,'=')+1);commit; |
STEP7.change the sqlcontent to upper, in order to make the sentence no sensitive.
update XXX_property_sql_tempSet sqlcontent=trim(upper(sqlcontent));commit; |
STEP8.Change the sql operate type, ‘INSERT’, ‘UPDATE’, ‘DELETE’, ‘SELECT’ is 6 character length.
update XXX_property_sql_tempSet peratetype=substr(sqlcontent,1,6);commit; |
STEP9.Process the sqltable only for‘UPDATE’ operation,get the table part between the first blank and the second blank.
update XXX_property_sql_tempSet SQLTABLE=substr(SQLCONTENT,instr(SQLCONTENT,' ')+1,INSTR(SQLCONTENT,' ',instr(SQLCONTENT,' ')+1)-instr(SQLCONTENT,' ')-1)where peratetype='UPDATE';commit; |
STEP10.Process the sqlWHERE only for‘UPDATE’ operation, get the where clause after ‘WHERE’ string.
update XXX_property_sql_tempSet SQLwhere=SUBSTR(SQLCONTENT,INSTR(SQLCONTENT,'WHERE')+6)where peratetype='UPDATE';commit; |
STEP11.Process the sqltable only for‘SELECT’ operation, get the table part between ‘WHERE’ and ‘FROM’
update XXX_property_sql_tempSet SQLTABLE=Trim(SUBSTR(SQLCONTENT,INSTR(SQLCONTENT,'FROM')+4,INSTR(SQLCONTENT,'WHERE')-INSTR(SQLCONTENT,'FROM')-4))where peratetype='SELECT'orOperatetype =’DELETE’; commit; |
STEP12.Process the sqlWHERE only for‘SELECT’ operation, get the where part after ‘WHERE’
update XXX_property_sql_tempSet SQLwhere=DECODE(INSTR(SQLCONTENT,'WHERE'),0,'',Trim(SUBSTR(SQLCONTENT,INSTR(SQLCONTENT,'WHERE')+5)))where peratetype='SELECT'orOperatetype =’DELETE’; commit; |
STEP13.Insert into the XXX_property_sql table from XXX_property_sql_temptable
insert into XXX_property_sql select * from XXX_property_sql_temp;commit; |
STEP13.Later then delete from XXX_property_sql_temp;
delete from XXX_property_sql_temp;commit; |
STEP14.Analyze the entire property files loop;STEP15.Analyze the tables and fields in where clause, and build the index script.
Select SQLTable,SQLWhere,OperateType,SQLContent |
Build index based on javadynamic SQL.The part is more like property file part, dynamic SQL usually is more complex, and all the SQL only captured from the log file. We must overall read the SQL and the business logic, then evaluate how to build the index.Build index based on data volume and table type fromcustomer’s estimation.Base the data volume and table type, we can choose those large data volume and frequently transaction table; the estimation can help us focus on the main table and transaction table.Check the DB performance view and find the Top N SQL consumed with high CPU, Memory and I/O.
STEP1.Query thev$session_longopsview and get the long time run SQL.This view displays the status of various operationsthat run for longer than 6 seconds(in absolute time). These operations currently include many backup and recovery functions, statistics gathering, and query execution, and more operations are added for every Oracle release.
SELECTse.sid,opname,TRUNC(sofar / totalwork * 100, 2) || '%' as pct_work,elapsed_seconds elapsed,ROUND(elapsed_seconds * (totalwork - sofar) / sofar) remain_time,sql_textFROM v$session_longops sl, v$sqlarea sa, v$session seWHERE sl.sql_hash_value = sa.hash_valueAND sl.sid = se.sidAND sl.serial#=se.serial#AND sofar != totalworkORDER BY start_time; |
STEP2.Query thev$sqlarea view and get thetop N SQL consumed disk;
SELECT * FROM(SELECT hash_value, executions, buffer_gets, disk_reads, parse_calls,sql_textFROM v$sqlareaORDER BY disk_reads Desc)Where ROWNUM<10; |
STEP3.Query thev$sqlarea view and get thetop N SQL that has bad performance;
SELECTexecutions ,disk_reads,buffer_gets,ROUND((buffer_gets-disk_reads)/buffer_gets,2) hit_radio,ROUND(disk_reads/executions,2) reads_per_run,sql_textFROM v$sqlareaWHERE executions>0AND buffer_gets > 0AND (buffer_gets-disk_reads)/buffer_gets < 0.8ORDER BY 10 DESC |
STEP4.Query the v$session_longops view andget the SQL full table scanned.
SELECT s.sql_textFROM (SELECT opname,target,b.num_rows,b.tablespace_name,sql_hash_value,count(target)FROM v$session_longops a,all_all_tables b |
导入论坛 引用链接 收藏 分享给好友 推荐到圈子 管理 举报
TAG:
标题搜索
日历
|
|||||||||
| 日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
| 1 | 2 | 3 | 4 | ||||||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 | |||
| 12 | 13 | 14 | 15 | 16 | 17 | 18 | |||
| 19 | 20 | 21 | 22 | 23 | 24 | 25 | |||
| 26 | 27 | 28 | 29 | 30 | 31 | ||||
数据统计
- 访问量: 25145
- 日志数: 66
- 建立时间: 2007-12-07
- 更新时间: 2008-09-28


