2. ABOUT ME
• 15+ years of database-centric experience
• Oracle Certified Developer 2000
• Oracle DBA since 2002
-Oracle 8i,10g,11g RAC Expert , E-Business Suite DBA OCP
• Other Credentials: SCJP, SAP (FI/CO)
• Different Roles
- Developer, DBA, Analyst, SW Architect
• Trainer – Oracle Core, RAC Curriculum
• Current JD
- Senior Database Architect, Manage Oracle & SQL Server DBAs
• Blog
- dbmentors.blogspot.com
Inam Ullah Bukhari
2
3. AGENDA
• What is Optimization?
• Why you need it? Tuning goals
• How is it done/how it works?
• Optimization Areas
Database Design (if it's not too late)
Application
Memory
I/O
Database Contention
3
4. WHAT/WHY - OPTIMIZATION?
• Achieving the best performance in shortest amount of time
• The use of system resources to perform work efficiently and
quickly to homogenize the performance of a database.
4
7. OPTIMIZING APPLICATION DESIGN
• Simplicity In Application Design
• Optimizing connection management
• Reducing the number of requests to the database using stored
procedures
• Reducing the number of requests to the database using
sequences
• Optimizing performance with schema De-Normalization
• Improving performance by sharing reusable code (Hard/Soft
Parsing)
• Reducing the number of requests to the database using
materialized views
• SQL Execution Efficiency - Avoiding dynamic SQL
7
8. DE-NORMALIZATION EXAMPLE
SET AUTOTRACE TRACEONLY
SELECT F.FIRSTNAME, F.LASTNAME, PK.DESCRIPTION AS PHONEKIND,
PA.WHENAVAILABLE AS AVAILABILITY, P.PHONENUMBER
FROM FRIEND F
INNER JOIN FRIEND_PHONE FP ON FP.FRIENDID = F.ID
INNER JOIN PHONE P ON P.ID = FP.PHONEID
INNER JOIN PHONEKIND PK ON PK.ID = P.PHONEKINDID
LEFT OUTER JOIN AVAILABILITY PA ON PA.ID = P.AVAILABILITYID
WHERE F.ID = 29912;
8
9. MATERIALIZED VIEW EXAMPLE
SELECT PROD_ID, SUM(AMOUNT_SOLD)
FROM SH.SALES GROUP BY PROD_ID;
CREATE MATERIALIZED VIEW
SH.MV_SALES_BY_PRODUCT
BUILD IMMEDIATE REFRESH ON COMMIT
ENABLE QUERY REWRITE AS
SELECT PROD_ID, SUM(AMOUNT_SOLD)
AS AMOUNT_SOLD FROM SH.SALES
GROUP BY PROD_ID;
9
10. AVOIDING DYNAMIC SQL EXAMPLE
SQL> declare
2 x number;
3 begin
4 for i in 1 .. 10
5 loop
6 execute immediate 'select count(*) from dual q1' into x;
7 select count(*) into x from dual q2;
8 end loop;
9 end;
10 /
-- sql_trace and tkprof
select count(*) from dual q1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- --------
Parse 10 0.00 0.00 0 0 0 0
Execute 10 0.00 0.00 0 0 0 0
Fetch 10 0.00 0.01 0 10 40 10
------- ------ -------- ---------- ---------- ---------- ---------- --------
total 30 0.00 0.01 0 10 40 10
*******************************************************************************
SELECT COUNT(*) FROM DUAL q2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- --------
Parse 1 0.00 0.00 0 0 0 0
Execute 10 0.00 0.00 0 0 0 0
Fetch 10 0.00 0.00 0 10 40 10
------- ------ -------- ---------- ---------- ---------- ---------- --------
total 21 0.00 0.00 0 10 40 10
10
- No compile time check
- No dependency mechanism (No clue)
- Overhead of doing dynamic stuff
11. OPTIMIZING STORAGE STRUCTURES
Chained Rows/Migrated Rows (using multiple block sizes)
ALTER SYSTEM SET db_16k_cache_size = 16m scope=both;
• Contention reduction
• Reduced row chaining
• Faster updates
• Reduced Pinging
• Less disk space waste
• Less RAM waste
• Minimize redo generation
• Faster scans
11
12. OPTIMIZING STORAGE STRUCTURES
• Using LOBs
- Separate Tablespace
- Cache,NoCache,CacheReads
• Indexing the correct way
- B-tree
- Reverse Key
- Function Based
- Bitmap
- Analyze
- Compress
• Using partitioning
- Partition Pruning
- Massive DML Operations in parallel
12
13. OPTIMIZING SQL CODE
PROCEDURE PNOBIND(CUSTID IN sh.customers.cust_id%TYPE)
IS
BEGIN
DECLARE aRow sh.customers%ROWTYPE;
l_stmt VARCHAR2(2000);
BEGIN
l_stmt := 'SELECT * FROM sh.customers s WHERE s.cust_id=‘ || TO_CHAR (CUSTID);
EXECUTE IMMEDIATE l_stmt INTO aRow;
…..
END ;
PROCEDURE PBIND(CUSTID IN sh.customers.cust_id%TYPE) IS
BEGIN
DECLARE aRow sh.customers%ROWTYPE;
l_stmt VARCHAR2(2000);
BEGIN
l_stmt := 'SELECT * FROM sh.customers s WHERE s.cust_id =:p_cust_id';
EXECUTE IMMEDIATE l_stmt INTO aRow USING CUSTID;
…..
END;
PROCEDURE TEST_BIND_STATIC(CUSTID IN sh.customers.cust_id%TYPE) IS
BEGIN
DECLARE aRow sh.customers%ROWTYPE;
BEGIN
SELECT * INTO aROW FROM sh.customers s WHERE s.cust_id =CUSTID;
…..
END;
50k Runs
• Bind Variables
• Concurrency
and scalability
13
14. OPTIMIZING SQL CODE
Avoiding full table scans (many I/O operations/buffer cache flush)
FTS - Small Tables
The High-Water Mark
14
17. OTHER OPTIMIZATIONS
Caching results - client-side result cache
ALTER SYSTEM SET CLIENT_RESULT_CACHE_SIZE=5M SCOPE=SPFILE;
ALTER SESSION SET RESULT_CACHE_MODE = FORCE
ALTER TABLE CUSTOMERS RESULT_CACHE (MODE FORCE);
SELECT /*+ result_cache */ COUNTRY_NAME, CUST_LAST_NAME, COUNT(*) ……..
Enabling parallel SQL
SELECT /*+ PARALLEL (S, 2) */ S.PROD_ID, S.CUST_ID, S.TIME_ID FROM SH.SALES S
ORDER BY S.AMOUNT_SOLD DESC;
Direct path inserting
/*+ APPEND */ hint for INSERT
17
22. OPTIMIZING MEMORY
• Avoid Operating System paging/Swapping
• AMM – Don’t use with hugepages and MTS
• Tuning the Library Cache (Hits & Misses)
22
23. OPTIMIZING MEMORY
Dictionary Cache
- Reduce DDL activities
- Use the CACHE option for Sequences
Program Global Area and the User Global Area
- OPEN_CURSORS
- SESSION_CACHED_CURSORS
- CURSOR_SHARING
Buffer Cache
- configure multiple Buffer Pools
23
24. OPTIMIZING I/O
• Redologs on disks without other activities
• Redo logs and Archived redo logs on separate disks
• Heavily accessed files on separate disk
• Distribute the data files based on disk controller allocation
• Separate disks for data that is not related to the database
• Striping objects across multiple disks
• Distribute table and related indexes on different disks
24
25. OPTIMIZING CONTENTION
Detecting and preventing lock contention
- V$LOCK, V$ENQUEUE_LOCK, V$ENQUEUE_LOCK,
DBA_WAITERS, DBA_BLOCKERS
Latches – Is there any Tuning?
- V$SYSTEM_EVENT
25