Back

    Query Profiling Across Database Engines

    Use EXPLAIN ANALYZE, pg_stat_statements, Performance Schema, and Query Store to find and fix slow queries.

    ๐ŸŽฏ What You'll Learn

    • PostgreSQL EXPLAIN with ANALYZE, BUFFERS, and VERBOSE
    • pg_stat_statements for finding top resource consumers
    • MySQL Performance Schema and slow query log
    • SQL Server Query Store and DMVs
    • A systematic 7-step profiling workflow

    ๐Ÿ”ฌ PostgreSQL EXPLAIN Deep Dive

    EXPLAIN ANALYZE is your most powerful diagnostic tool. Adding BUFFERS shows I/O details, and VERBOSE shows column-level information. Think of it as a medical scan for your query.

    ๐Ÿ’ก Pro Tip โ€” actual rows vs planned rows

    If actual rows are 100x different from planned rows, the optimizer made a bad plan due to stale statistics. Run ANALYZE tablename; to refresh.

    EXPLAIN ANALYZE

    Full diagnostic output with buffers and timing

    Try it Yourself ยป
    SQL
    -- PostgreSQL: EXPLAIN ANALYZE with all options
    
    -- Full diagnostic output:
    EXPLAIN (ANALYZE, BUFFERS, TIMING, VERBOSE, FORMAT TEXT)
    SELECT c.name, COUNT(o.id) AS order_count, SUM(o.total) AS total_spent
    FROM customers c
    JOIN orders o ON c.id = o.customer_id
    WHERE o.order_date >= '2024-01-01'
    GROUP BY c.name
    HAVING SUM(o.total) > 1000
    ORDER BY total_spent DESC
    LIMIT 20;
    
    -- Key metrics to read:
    -- actual time=0.015..45.230   (startup..total in ms)
    -- rows=20                     (actual rows retu
    ...

    ๐Ÿ“Š pg_stat_statements

    pg_stat_statements aggregates statistics across all executions of each query pattern. It tells you which queries consume the most total time โ€” even if each individual execution is fast.

    pg_stat_statements

    Find top resource-consuming queries

    Try it Yourself ยป
    SQL
    -- pg_stat_statements: find your slowest queries
    -- (Must be enabled in postgresql.conf)
    -- shared_preload_libraries = 'pg_stat_statements'
    
    SELECT
        LEFT(query, 80) AS query_preview,
        calls,
        ROUND(total_exec_time::numeric / 1000, 2) AS total_seconds,
        ROUND(mean_exec_time::numeric, 2) AS avg_ms,
        ROUND(max_exec_time::numeric, 2) AS max_ms,
        rows AS total_rows,
        ROUND((shared_blks_hit::decimal /
            NULLIF(shared_blks_hit + shared_blks_read, 0)) * 100, 1)
            AS cach
    ...

    ๐Ÿฌ MySQL Profiling

    MySQL uses Performance Schema and the slow query log. MySQL 8.0+ supports EXPLAIN ANALYZE similar to PostgreSQL.

    MySQL Profiling

    Performance Schema, slow log, and EXPLAIN

    Try it Yourself ยป
    SQL
    -- MySQL: Performance Schema and EXPLAIN ANALYZE
    
    -- Enable performance monitoring:
    -- performance_schema = ON  (in my.cnf)
    
    -- MySQL 8.0+ EXPLAIN ANALYZE (actually runs the query):
    -- EXPLAIN ANALYZE
    -- SELECT c.name, COUNT(*) FROM customers c
    -- JOIN orders o ON c.id = o.customer_id
    -- GROUP BY c.name LIMIT 10;
    
    -- MySQL slow query log:
    -- slow_query_log = ON
    -- slow_query_log_file = /var/log/mysql/slow.log
    -- long_query_time = 1  (log queries > 1 second)
    
    -- Find slow queries in Performance S
    ...

    ๐Ÿ”ท SQL Server Query Store

    SQL Server's Query Store automatically captures execution plans and runtime statistics over time, making it easy to find regressions and compare plan changes.

    SQL Server Query Store

    Query Store, DMVs, and missing index suggestions

    Try it Yourself ยป
    SQL
    -- SQL Server: Query Store and Execution Plans
    
    -- Enable Query Store:
    -- ALTER DATABASE mydb SET QUERY_STORE = ON;
    
    -- Find top resource-consuming queries:
    -- SELECT TOP 20
    --     qs.query_id,
    --     qt.query_sql_text,
    --     rs.avg_duration / 1000.0 AS avg_ms,
    --     rs.count_executions,
    --     rs.avg_logical_io_reads,
    --     rs.avg_cpu_time / 1000.0 AS avg_cpu_ms
    -- FROM sys.query_store_runtime_stats rs
    -- JOIN sys.query_store_plan qp ON rs.plan_id = qp.plan_id
    -- JOIN sys.query_store_query q
    ...

    ๐Ÿ”„ Systematic Profiling Workflow

    โš ๏ธ Common Mistake

    Optimizing the slowest single query instead of the highest total-time query. A query running 50ms ร— 100,000 times/day (5,000 seconds total) matters more than one running 10 seconds ร— 2 times/day (20 seconds total).

    Profiling Workflow

    7-step systematic performance tuning

    Try it Yourself ยป
    SQL
    -- PROFILING WORKFLOW: systematic performance tuning
    
    -- Step 1: IDENTIFY slow queries
    -- Use pg_stat_statements, slow query log, or APM tools
    -- Focus on: highest total time (not just slowest single execution)
    
    -- Step 2: ANALYZE the execution plan
    EXPLAIN (ANALYZE, BUFFERS)
    SELECT * FROM orders
    WHERE customer_id = 42 AND status = 'pending';
    -- Look for: Seq Scan, high actual rows, buffer reads
    
    -- Step 3: CHECK statistics freshness
    SELECT relname, last_analyze, last_autoanalyze,
           n_live_
    ...

    ๐Ÿ“‹ Quick Reference

    DatabaseProfiling Tool
    PostgreSQLEXPLAIN ANALYZE + pg_stat_statements
    MySQLPerformance Schema + slow query log
    SQL ServerQuery Store + DMVs
    AllAPM tools (Datadog, New Relic)

    ๐ŸŽ‰ Lesson Complete!

    You can now profile queries across PostgreSQL, MySQL, and SQL Server. Next, dive into buffer pool and memory optimization!

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy Policy โ€ข Terms of Service