Skip to content

SQL Performance Optimization: Finding the Right Queries to Fix

cpx September 22, 2025 6 min read Database MYSQL/3306

Database performance can make or break your application’s user experience. When your SQL queries are running slowly, users feel it immediately through sluggish page loads and unresponsive interfaces. The challenge isn’t just fixing slow queries – it’s identifying which ones to fix first.

This guide walks through proven methods for finding problematic SQL queries, from simple local debugging to advanced production analysis techniques. Each method serves a different purpose in your optimization toolkit.

The Impact of Query Optimization

Before diving into identification techniques, it’s worth understanding the potential impact. A few weeks ago, we massively improved the performance of the dashboard & website by optimizing some of our SQL queries. The results were dramatic – response times dropped significantly across the board, proving that targeted query optimization can yield massive performance gains.

Query Identification Methods

Here are the most effective approaches for finding queries that need optimization, organized from simplest to most advanced:

MethodComplexityEnvironmentBest ForLimitations
Debug BarBeginnerLocalQuick wins, duplicate queriesDevelopment only
Slow Query LogIntermediateAllLong-running queriesRequires threshold tuning
Non-indexed Query LogIntermediateAllMissing indexesCan be noisy
Live Process AnalysisAdvancedAllCurrently running queriesLimited to active queries
General Query LogAdvancedLocal/StagingMost frequent queriesHigh I/O impact

Method 1: Debug Bar Analysis

The easiest place to start investigating queries is locally, in your development environment. For Laravel applications, the barryvdh/laravel-debugbar package provides excellent insights right in your browser.

The debug bar shows you three critical metrics at a glance:

  • Total time spent executing SQL queries
  • Total number of queries executed
  • Number of duplicate queries (indicating N+1 issues)

Key insight: Before optimizing any query, ask whether it can be avoided entirely. Duplicate queries often indicate N+1 problems or unnecessary data loading.

Method 2: MySQL Slow Query Log

This is your first production-ready tool for identifying problematic queries. MySQL can automatically log any query exceeding your defined threshold.

Setup process:

# Create the log file
touch /var/log/mysql-slow-query.log
chown mysql:mysql /var/log/mysql-slow-query.log
-- Enable slow query logging
SET GLOBAL slow_query_log_file = '/var/log/mysql-slow-query.log';
SET GLOBAL long_query_time = 1;  -- 1 second threshold
SET GLOBAL slow_query_log = 'ON';

Advanced configuration options:

SettingPurposeExample Value
long_query_timeQuery duration threshold0.3 (300ms)
min_examined_row_limitMinimum rows examined1000
Persistent configAdd to my.cnf for permanenceSee configuration block

For permanent configuration, add this to your my.cnf:

[mysqld]
slow_query_log = ON
slow_query_log_file = /var/log/mysql-slow-query.log
long_query_time = 1

Method 3: Non-Indexed Query Detection

A fast query usually has indexes on them that make retrieving the data blazing fast. MySQL can identify queries that aren’t using indexes for lookups.

SET GLOBAL log_queries_not_using_indexes = ON;
SET GLOBAL min_examined_row_limit = 1000;  -- Optional: reduce noise

Common non-indexed query patterns:

PatternExampleWhy No Index Used
Full table scanSELECT * FROM usersNo WHERE clause
Non-indexed columnSELECT * FROM users WHERE email = '[email protected]'No index on email
Function on indexed columnSELECT * FROM users WHERE UPPER(email) = '[email protected]'Function prevents index usage
Leading wildcardSELECT * FROM users WHERE name LIKE '%john%'Leading % prevents index usage

Important: This setting can be noisy and impact performance on busy servers. Enable it temporarily for analysis, then disable it:

SET GLOBAL log_queries_not_using_indexes = OFF;

Method 4: Live Query Analysis

As a rule of thumb, I like to use: whenever I can see a query being executed right now, it probably can use some optimisations. The logic is simple – fast queries finish so quickly they rarely appear in process lists.

Basic process list:

SHOW FULL PROCESSLIST;

Filtered analysis:

SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO 
FROM performance_schema.processlist 
WHERE DB = 'your_database' AND COMMAND != 'Sleep';

Millisecond-precision analysis:

SELECT t.processlist_id, t.processlist_user, t.processlist_host, 
       t.processlist_db, t.processlist_command, t.processlist_state, 
       t.processlist_info, ROUND(s.timer_wait/1000000, 2) as execution_time_ms
FROM performance_schema.threads t 
JOIN performance_schema.events_statements_current s ON t.thread_id = s.thread_id 
WHERE t.processlist_command != 'Sleep' 
  AND s.timer_wait IS NOT NULL 
ORDER BY s.timer_wait DESC;

Method 5: General Query Log Analysis

⚠️ Warning: On high-traffic MySQL servers, this will become a major bottleneck! Use this method only in development or staging environments.

This method logs every single query, allowing you to identify the most frequently executed ones.

Setup:

touch /var/log/mysql-general-query.log
chown mysql:mysql /var/log/mysql-general-query.log
SET GLOBAL general_log_file = '/var/log/mysql-general-query.log';
SET GLOBAL general_log = ON;

Analysis with Percona Toolkit:

# Install Percona Toolkit
apt install percona-toolkit  # Debian/Ubuntu
brew install percona-toolkit  # macOS

# Process the log for prepared statements
sed 's/Execute\t/Query\t/' /var/log/mysql-general-query.log > /var/log/mysql-general-query-edited.log

# Analyze query frequency and performance
pt-query-digest \
  --type=genlog \
  --group-by fingerprint \
  --order-by Query_time:cnt,Query_time:sum \
  --filter '$event->{cmd} =~ /^(Query|Execute)$/' \
  --limit 25 \
  /var/log/mysql-general-query-edited.log

MySQL CLI Productivity Tips

TechniqueCommandPurpose
Vertical outputAdd \G to queryBetter readability for wide results
Output to file\T /tmp/output.logEnable file logging
Stop file logging\tDisable file logging

Example of vertical output:

-- Instead of wide horizontal tables:
SELECT id, name FROM teams LIMIT 2;

-- Use vertical format for better readability:
SELECT id, name FROM teams LIMIT 2 \G;

Framework-Specific: Laravel N+1 Prevention

For Laravel applications, you can automatically detect N+1 query problems by adding this to your AppServiceProvider:

public function boot(): void
{
    Model::preventLazyLoading(! $this->app->isProduction());
}

This will throw exceptions when lazy loading occurs, helping you identify and fix N+1 issues before they reach production.

Common N+1 fix pattern:

// Problem: N+1 queries
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->comments->count();  // Executes query for each post
}

// Solution: Eager loading
$posts = Post::withCount('comments')->get();
foreach ($posts as $post) {
    echo $post->comments_count;  // Uses pre-loaded count
}

Optimization Strategy

When you’ve identified problematic queries using these methods, prioritize them based on:

  1. Frequency – Queries executed most often
  2. Impact – Longest-running queries
  3. Ease of fix – Simple index additions vs. complex query rewrites

Remember: Improving a query from 25ms to 20ms may sound negligible, but if it’s performed millions of times a day, it adds up.

Next Steps

Query identification is just the beginning. Once you’ve found your problematic queries, the next phase involves understanding why they’re slow and implementing the right fixes – whether that’s adding indexes, rewriting queries, or restructuring your data access patterns.

The methods outlined here give you a comprehensive toolkit for finding optimization opportunities. Start with the simpler approaches like debug bars and slow query logs, then graduate to more advanced techniques as your optimization needs become more sophisticated.


Ready to take your database performance to the next level? These identification techniques are your first step toward building faster, more responsive applications that your users will love.

0 0 votes
Article Rating
guest

0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x
()
x