Md Mominul Islam | Software and Data Enginnering | SQL Server, .NET, Power BI, Azure Blog

while(!(succeed=try()));

LinkedIn Portfolio Banner

Latest

Home Top Ad

Responsive Ads Here

Post Top Ad

Responsive Ads Here

Monday, September 1, 2025

How to Identify and Fix Slow-Running SQL Queries in Oracle Database: A Comprehensive Guide

 

Introduction

Slow-running SQL queries can cripple an Oracle Database’s performance, leading to frustrated users and inefficient applications. Whether you're a beginner DBA or an experienced developer, understanding how to identify and fix these bottlenecks is critical. This comprehensive guide walks you through the process with real-life examples, practical scripts, and actionable insights. From basic query analysis to advanced optimization techniques, we’ll cover it all, ensuring your queries run faster and your database performs at its best.


Why SQL Queries Run Slowly

Before diving into solutions, let’s understand why SQL queries might lag:

  • Inefficient Query Design: Poorly written queries with unnecessary joins or subqueries.

  • Missing or Suboptimal Indexes: Lack of proper indexes or outdated statistics.

  • Large Data Volumes: Queries scanning massive datasets without filtering.

  • Resource Contention: CPU, memory, or I/O bottlenecks.

  • Outdated Statistics: Optimizer making poor decisions due to stale metadata.

  • Complex Joins or Aggregations: Overly complex operations consuming resources.

By addressing these issues systematically, you can significantly improve query performance.


Step 1: Identifying Slow-Running Queries

To fix slow queries, you first need to identify them. Oracle provides several tools and techniques to pinpoint problematic queries.

1.1 Using V$SQL and V$SESSION

The V$SQL view stores details about executed SQL statements, while V$SESSION provides session-level information. You can query these to find queries with high execution times or resource usage.

Example Query to Identify Slow Queries

SELECT 
    sql_id,
    sql_text,
    executions,
    elapsed_time / 1000000 AS elapsed_seconds,
    disk_reads,
    buffer_gets
FROM 
    v$sql
WHERE 
    elapsed_time > 1000000 -- Queries taking more than 1 second
    AND executions > 0
ORDER BY 
    elapsed_time DESC
FETCH FIRST 10 ROWS ONLY;

Explanation:

  • elapsed_time is in microseconds, so divide by 1,000,000 to get seconds.

  • disk_reads and buffer_gets indicate I/O and memory usage.

  • This query lists the top 10 slowest queries based on total execution time.

Real-Life Scenario: Imagine you’re a DBA for an e-commerce platform. Users report slow response times when searching for products. Running the above query reveals a query with sql_id = 'abc123' taking 5 seconds due to high disk_reads. This is your target for optimization.

1.2 Using Automatic Workload Repository (AWR)

AWR reports provide a historical view of database performance. Generate an AWR report for a specific period to identify slow queries.

Steps:

  1. Run the AWR report script: @$ORACLE_HOME/rdbms/admin/awrrpt.sql

  2. Choose a snapshot range (e.g., last 24 hours).

  3. Analyze the “SQL Statistics” section for high elapsed time queries.

Pros:

  • Comprehensive historical data.

  • Identifies resource-intensive queries across workloads.

Cons:

  • Requires Diagnostic Pack license.

  • May overwhelm beginners with data volume.

Alternative: Use Active Session History (ASH) for real-time analysis without a license.

1.3 Using SQL Trace and TKPROF

SQL Trace provides detailed execution plans and statistics for specific sessions.

Steps:

  1. Enable tracing for a session:

ALTER SESSION SET sql_trace = TRUE;
-- Run your query here
ALTER SESSION SET sql_trace = FALSE;
  1. Use TKPROF to format the trace file:

tkprof <trace_file>.trc output.txt sys=no sort=execpu
  1. Analyze the output for high-cost operations.

Real-Life Example: For the e-commerce platform, you trace a product search query and find it performs a full table scan on a 10-million-row PRODUCTS table. This indicates a missing index.


Step 2: Analyzing Query Execution Plans

Once you’ve identified slow queries, analyze their execution plans to understand how Oracle processes them.

2.1 Using EXPLAIN PLAN

The EXPLAIN PLAN command shows the execution plan without running the query.

Example:

EXPLAIN PLAN FOR
SELECT p.product_name, c.category_name
FROM products p
JOIN categories c ON p.category_id = c.category_id
WHERE p.price > 100;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

Sample Output:

------------------------------------------------------
| Id  | Operation          | Name       | Rows  | Cost |
------------------------------------------------------
|   0 | SELECT STATEMENT   |            |  5000 |  1500|
|   1 |  HASH JOIN         |            |  5000 |  1500|
|   2 |   TABLE ACCESS FULL| PRODUCTS   | 10000 |   800|
|   3 |   TABLE ACCESS FULL| CATEGORIES |   100 |   200|
------------------------------------------------------

Observation: The TABLE ACCESS FULL on PRODUCTS suggests a full table scan, which is costly for large tables.

2.2 Using DBMS_XPLAN.DISPLAY_CURSOR

For real-time plans of executed queries, use DBMS_XPLAN.DISPLAY_CURSOR.

Example:

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('abc123', NULL, 'ALLSTATS LAST'));

Pros:

  • Shows actual execution statistics, not just estimates.

  • Includes runtime metrics like rows processed and I/O.

Cons:

  • Requires the sql_id of the query.

  • May need additional permissions.

Best Practice: Always compare estimated (from EXPLAIN PLAN) and actual (from DBMS_XPLAN.DISPLAY_CURSOR) plans to identify discrepancies.


Step 3: Fixing Slow-Running Queries

Now that you’ve identified and analyzed slow queries, let’s fix them using various techniques.

3.1 Optimizing Query Structure

Poorly written queries often cause performance issues. Simplify and optimize your SQL.

Example: Inefficient Subquery

SELECT product_name
FROM products
WHERE category_id IN (
    SELECT category_id
    FROM categories
    WHERE category_name = 'Electronics'
);

Optimized Version:

SELECT p.product_name
FROM products p
JOIN categories c ON p.category_id = c.category_id
WHERE c.category_name = 'Electronics';

Why It’s Better:

  • Joins are often faster than subqueries.

  • Reduces redundant data access.

Real-Life Scenario: In the e-commerce platform, rewriting a subquery-based product search reduced execution time from 3 seconds to 0.5 seconds.

3.2 Adding or Modifying Indexes

Indexes can drastically reduce query execution time by avoiding full table scans.

Example: Create an index on the price column for the PRODUCTS table.

CREATE INDEX idx_products_price ON products(price);

After Index Execution Plan:

------------------------------------------------------
| Id  | Operation          | Name              | Rows  | Cost |
------------------------------------------------------
|   0 | SELECT STATEMENT   |                   |  5000 |   300|
|   1 |  HASH JOIN         |                   |  5000 |   300|
|   2 |   INDEX RANGE SCAN | IDX_PRODUCTS_PRICE|  5000 |   100|
|   3 |   TABLE ACCESS FULL| CATEGORIES        |   100 |   200|
------------------------------------------------------

Pros:

  • Speeds up WHERE, JOIN, and ORDER BY operations.

  • Reduces I/O by accessing only relevant rows.

Cons:

  • Increases storage and maintenance overhead.

  • Slows down INSERT, UPDATE, and DELETE operations.

Best Practice: Use composite indexes for queries filtering on multiple columns, e.g., CREATE INDEX idx_products_cat_price ON products(category_id, price).

3.3 Updating Statistics

The Oracle optimizer relies on accurate statistics to choose the best execution plan.

Example:

EXEC DBMS_STATS.GATHER_TABLE_STATS('SCHEMA_NAME', 'PRODUCTS');

Real-Life Scenario: After updating statistics on the PRODUCTS table, a query’s execution plan switched from a full table scan to an index range scan, reducing runtime by 60%.

Best Practice: Schedule regular statistics updates using DBMS_SCHEDULER to avoid stale data.

3.4 Partitioning Large Tables

For very large tables, partitioning can improve performance by dividing data into manageable chunks.

Example: Partition the PRODUCTS table by category_id.

CREATE TABLE products (
    product_id NUMBER,
    category_id NUMBER,
    product_name VARCHAR2(100),
    price NUMBER
)
PARTITION BY RANGE (category_id) (
    PARTITION p1 VALUES LESS THAN (100),
    PARTITION p2 VALUES LESS THAN (200),
    PARTITION p3 VALUES LESS THAN (MAXVALUE)
);

Pros:

  • Improves query performance by scanning only relevant partitions.

  • Simplifies maintenance tasks like archiving.

Cons:

  • Adds complexity to table management.

  • Requires Enterprise Edition.

Alternative: Use subpartitions or materialized views for smaller datasets.

3.5 Using Hints

SQL hints influence the optimizer’s execution plan.

Example: Force an index scan.

SELECT /*+ INDEX(p idx_products_price) */ product_name
FROM products p
WHERE price > 100;

Pros:

  • Provides fine-grained control over execution plans.

  • Useful for testing alternative plans.

Cons:

  • Can make queries less adaptable to data changes.

  • Requires deep understanding of the optimizer.

Best Practice: Use hints sparingly and validate their impact using EXPLAIN PLAN.


Step 4: Monitoring and Maintenance

Optimization is an ongoing process. Implement these practices to maintain performance:

  • Regular Monitoring: Use Oracle Enterprise Manager or custom scripts to track query performance.

  • Automated Jobs: Schedule index rebuilds and statistics updates.

  • Query Rewrites: Periodically review and refactor frequently executed queries.

  • Hardware Upgrades: Consider increasing memory or CPU if software optimizations aren’t enough.

Example Monitoring Script:

SELECT 
    sql_id,
    sql_text,
    executions,
    elapsed_time / 1000000 AS avg_elapsed_seconds
FROM 
    v$sql
WHERE 
    executions > 100
    AND elapsed_time / executions > 1000000 -- Average time > 1 second
ORDER BY 
    elapsed_time / executions DESC;

Advanced Techniques

For complex environments, consider these advanced strategies:

  • Parallel Execution: Use the PARALLEL hint to distribute query workload across multiple CPUs.

SELECT /*+ PARALLEL(p, 4) */ product_name
FROM products p
WHERE price > 100;
  • Materialized Views: Precompute and store query results for frequently accessed data.

  • SQL Plan Baselines: Lock efficient execution plans to prevent regressions after upgrades.

EXEC DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(sql_id => 'abc123');

Pros and Cons of Optimization Techniques

Technique

Pros

Cons

Indexing

Fast data retrieval

Increased storage, slower DML

Query Rewriting

Improves efficiency without overhead

Requires developer expertise

Partitioning

Scalable for large datasets

Complex setup, licensing costs

Hints

Precise control over plans

May break with data changes

Statistics Updates

Better optimizer decisions

Maintenance overhead


Best Practices and Standards

  1. Write Efficient SQL: Avoid SELECT *, use specific columns, and minimize subqueries.

  2. Index Wisely: Create indexes based on query patterns, but avoid over-indexing.

  3. Test Changes: Use a test environment to validate optimizations before production.

  4. Monitor Regularly: Set up alerts for slow queries using tools like OEM or custom scripts.

  5. Document Changes: Maintain a log of optimizations for future reference.


Real-Life Case Study

Scenario: An e-commerce company noticed slow product search queries impacting user experience. Using V$SQL, the DBA identified a query with high elapsed_time. The execution plan showed a full table scan on the PRODUCTS table (10 million rows).

Actions:

  1. Added an index on price and category_id.

  2. Rewrote the query to use a JOIN instead of a subquery.

  3. Updated table statistics.

  4. Partitioned the PRODUCTS table by category_id.

Result: Query execution time dropped from 5 seconds to 0.3 seconds, improving user satisfaction.


Conclusion

Optimizing slow-running SQL queries in Oracle Database requires a systematic approach: identify problematic queries, analyze execution plans, and apply targeted fixes like indexing, query rewriting, or partitioning. By following best practices and leveraging Oracle’s powerful tools, you can ensure your database performs efficiently, even under heavy workloads. Start with the basics, monitor continuously, and explore advanced techniques as needed to keep your Oracle Database running smoothly.

No comments:

Post a Comment

Thanks for your valuable comment...........
Md. Mominul Islam

Post Bottom Ad

Responsive Ads Here