Database AdministrationUnit 811 min read
Oracle Performance Tuning: SQL & AWR – Locks, SQL Analysis & AWR Reports
Unit 8 of Database Administration: Covers Oracle’s locking mechanisms, SQL tuning techniques (execution plans, bind variables, indexes), and the Automatic Workload Repository (AWR) for performance monitoring, including how to interpret AWR reports, identify bottlenecks, and apply fixes with real-world examples from Nep
TAKEAWAYS:
- Oracle uses locking levels (row, table, DML, transaction, schema, and system locks) to manage concurrency, with methods like
SELECT FOR UPDATEandLOCK TABLEto acquire them. - SQL tuning relies on execution plans (via
EXPLAIN PLAN), bind variables (to avoid hard parsing), and proper indexing (B-tree vs. bitmap) to reduce I/O and CPU overhead. - The AWR automatically captures historical performance data (wait events, CPU usage, buffer cache hits) and generates reports (
awrrpt.sql) to pinpoint bottlenecks. - Real-world impact: Nepal’s Ncell uses AWR to optimize call routing during peak hours, while Daraz tunes SQL queries to handle 10,000+ concurrent orders during festivals.
- Worked example: A slow
SELECT * FROM orders WHERE customer_id = 1234can be fixed by adding a composite index on(customer_id, order_date)and checking the execution plan. - Exam focus: Link SQL tuning to AWR reports (e.g., "The AWR shows 90% of CPU time is spent on
PARSING IN CURSOR—suggest using bind variables").
1. Oracle Locking Mechanisms: Levels and Acquisition
Oracle enforces locking to prevent concurrent transactions from corrupting data. Locks are hierarchical, from fine-grained (row) to coarse-grained (system).
Locking Levels in Oracle
- System Lock: Global resource (e.g.,
ALTER DATABASE). - Schema Lock: Schema-level DDL operations (e.g.,
CREATE TABLE). - Table Lock: Exclusive lock on a table during
ALTER TABLE. - DML Lock: Shared (
SELECT) or exclusive (INSERT/UPDATE/DELETE) locks on rows. - Transaction Lock: Holds until commit/rollback.
- Row Lock: Granularity for row-level operations.
How Locks Are Acquired
| Method | Example | Lock Type |
|---|---|---|
SELECT FOR UPDATE |
SELECT * FROM accounts FOR UPDATE |
Row-level exclusive |
LOCK TABLE |
LOCK TABLE employees IN EXCLUSIVE MODE |
Table-level |
ALTER TABLE |
ALTER TABLE products ADD COLUMN |
Schema-level |
DDL statements |
CREATE INDEX idx_customer |
Schema-level |
| Deadlocks | Two transactions waiting for each other’s locks | Resolved via ALTER SYSTEM KILL SESSION |
Worked Example: Deadlock in Nepal’s NTC Call Center Two agents, Agent A and Agent B, try to update the same customer’s bill status:
- Agent A locks row
customer_id=1001(status: "pending"). - Agent B locks row
customer_id=1001(status: "paid"). - Deadlock: Both wait indefinitely. Oracle resolves it by killing one session:
SELECT sid, serial# FROM v$locked_object WHERE owner = 'NTC'; ALTER SYSTEM KILL SESSION '123,456' IMMEDIATE;
2. SQL Tuning: Execution Plans and Bind Variables
Slow SQL queries waste resources. Oracle provides tools to diagnose and fix them.
erDiagram
CUSTOMERS ||--o{ ORDERS : "places"
ORDERS ||--o{ ORDER_ITEMS : "contains"
CUSTOMERS {
int customer_id PK
string customer_name
string country
}
ORDERS {
int order_id PK
int customer_id FK
date order_date
}
ORDER_ITEMS {
int item_id PK
int order_id FK
int product_id FK
int quantity
}Example schema for SQL tuning analysis (Ncell’s customer orders)Execution Plans with EXPLAIN PLAN
EXPLAIN PLAN FOR SELECT customer_name FROM customers WHERE country = 'Nepal';
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
Output Interpretation:
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
|-----|--------------------|--------------|-------|-------|------------|----------|
| 0 | SELECT STATEMENT | | 1 | 12 | 3 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN | idx_country | 1 | 12 | 3 (0)| 00:00:01 |
INDEX RANGE SCAN: Ideal (uses index).FULL TABLE SCAN: Bad (scans entire table).
Fix: Add a missing index:
CREATE INDEX idx_country ON customers(country);
Bind Variables vs. Hard Parsing
- Hard Parsing: Oracle recompiles SQL for every execution (slow).
- Bind Variables: Reuse execution plans (fast).
-- Bad: Hard parsing EXECUTE IMMEDIATE 'SELECT * FROM orders WHERE order_id = ' || order_id; -- Good: Bind variable v_order_id := 1234; EXECUTE IMMEDIATE 'SELECT * FROM orders WHERE order_id = :order_id' USING v_order_id;
Real-World Tie: Daraz’s Festival Sales During Tihar, Daraz processes 10,000+ orders/sec. A poorly tuned query like:
SELECT product_name FROM products WHERE category = 'Electronics' AND price < 5000;
could trigger a full table scan. Solution:
- Add a composite index:
CREATE INDEX idx_category_price ON products(category, price). - Use bind variables in stored procedures to avoid hard parsing.
3. Automatic Workload Repository (AWR)
AWR automatically captures database performance metrics every hour and stores them in the DBA_HIST_* views. Key components:
- Snapshot: Captures CPU, I/O, waits, and buffer cache stats.
- Baseline: Compares current performance to historical baselines.
- Report: Generated via
awrrpt.sql.
AWR Report Key Metrics
Example AWR Snippet:
Wait Event: "db file sequential read" - 30% of CPU time
Top SQL: "SELECT * FROM sales WHERE date > SYSDATE - 7" (Cost: 1000)
Suggestion: Add index on `sales(date)`.
Generating an AWR Report
-- Run as SYSDBA
@?/rdbms/admin/awrrpt.sql
Output Highlights:
| Metric | Value | Interpretation |
|---|---|---|
| CPU Time | 85% | Most time spent in CPU (tune SQL) |
| Redo Size | 1.2 GB | High redo → check for long-running DML |
| Buffer Cache Hit | 95% | Good (low I/O) |
Worked Example: Ncell’s Call Routing Ncell’s database slows down during midnight peak hours. The AWR report shows:
Top Wait Event: "enq: TX - row lock contention" (25%)
Solution:
- Add row-level locks to high-contention tables:
ALTER TABLE call_logs ADD CONSTRAINT pk_call_logs PRIMARY KEY (call_id, timestamp); - Partition large tables by time:
CREATE TABLE call_logs ( call_id NUMBER, timestamp DATE, -- ... ) PARTITION BY RANGE (timestamp) ( PARTITION p_jan VALUES LESS THAN (TO_DATE('01-FEB-2023', 'DD-MON-YYYY')) );
4. Performance Tuning Techniques
| Technique | When to Use | Example |
|---|---|---|
| Indexing | Frequent WHERE clauses |
CREATE INDEX idx_customer ON orders(customer_id) |
| Partitioning | Large tables (>100GB) | Partition sales by month |
| Materialized Views | Aggregations run daily | CREATE MATERIALIZED VIEW mv_daily_sales |
| SQL Profile | Repeated slow queries | DBMS_SQLTUNE.CREATE_SQL_PROFILE |
| Resource Manager | Priority-based workloads | ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = 'high_priority' |
Advantages/Disadvantages:
| Technique | Pros | Cons |
|---|---|---|
| Indexing | Faster WHERE clauses |
Slower INSERT/UPDATE |
| Partitioning | Easier maintenance | Complex DML |
| Materialized Views | Pre-computed data | Storage overhead |
5. Real-World Applications
In the Real World
Nepal Rastra Bank (NRB) – Loan Processing
- Idea: AWR monitors slow SQL during loan approval season.
- How: NRB’s AWR report flags a query:
Fix: Added a composite index onSELECT applicant_name FROM loans WHERE status = 'pending' AND amount > 500000;(status, amount)and usedSELECT * FROM loans WHERE status = :status AND amount > :amount.
Khalti – Payment Gateway
- Idea: Bind variables prevent hard parsing during high transaction volumes.
- How: Khalti’s stored procedures use bind variables for:
-- Instead of: EXECUTE IMMEDIATE 'UPDATE transactions SET status = ''completed'' WHERE txn_id = ' || txn_id; -- Use: v_txn_id := 'txn_12345'; EXECUTE IMMEDIATE 'UPDATE transactions SET status = ''completed'' WHERE txn_id = :txn_id' USING v_txn_id;
NTC – Call Center Automation
- Idea: Deadlock resolution via
LOCK TABLEprevents call drops. - How: NTC locks high-contention tables during peak hours:
LOCK TABLE call_records IN EXCLUSIVE MODE; -- Perform bulk updates UNLOCK TABLE call_records;
- Idea: Deadlock resolution via
Exam Tip
- Link SQL tuning to AWR: Always mention how an AWR report (e.g., high
db file sequential read) leads to a specific fix (e.g., add an index). - Deadlocks: Explain with a real scenario (e.g., NTC agents) and the
ALTER SYSTEM KILL SESSIONcommand. - Bind variables: Contrast with hard parsing in exam questions—show how bind variables reduce parsing overhead.
- AWR report structure: Know the key sections (top SQL, wait events, CPU usage) and how to interpret them.
- Indexing trade-offs: Discuss when to use B-tree (OLTP) vs. bitmap (data warehousing) indexes.
Sample Answer Structure for Exam:
- Locking Levels: Explain row/table/transaction locks with a diagram.
- Deadlock Example: Describe NTC’s call center deadlock and resolution.
- SQL Tuning: Show
EXPLAIN PLANoutput and suggest an index. - AWR Report: Paste a snippet and explain the top wait event.
- Real-World Fix: Apply the fix (e.g., add index) and quantify improvement (e.g., "reduced query time from 5s to 0.1s").
In the real world
- Ncell’s Call Routing System: Uses AWR reports to detect
enq: TX - row lock contentionduring midnight peak hours (25% of wait events) and partitionscall_logstable bytimestampto reduce lock contention. - Daraz’s Festival Sales: Implements bind variables in stored procedures to avoid hard parsing during Tihar (10,000+ orders/sec) and adds composite indexes on
(category, price)to optimizeSELECT product_name FROM products WHERE category = 'Electronics' AND price < 5000. - Nepal Rastra Bank’s Core Banking: Employs row-level locks (
SELECT FOR UPDATE) for high-frequency transactions (e.g.,ALTER TABLE accounts LOCK ROWSduring batch processing) to prevent deadlocks in multi-branch operations.
Based on the TU BIT syllabus for Database Administration (BIT352), unit 8.
Discussion
Loading…