DEV Community

MD ARIFUL HAQUE
MD ARIFUL HAQUE

Posted on

Some Common SQL Slow Query Statements and How to Optimize Them...

Slow SQL queries can severely impact the performance of an application, especially when dealing with large datasets. Understanding common slow SQL query patterns and optimizing them is critical for database efficiency. Below are some common SQL slow query patterns and strategies on how to optimize them, followed by a detailed explanation of when to use certain optimizations and when not to.

1. Missing Indexes

  • Why it’s slow: Without indexes, SQL must scan the entire table (full table scan) to find relevant rows.
  • How to optimize: Add appropriate indexes on columns used in WHERE, JOIN, GROUP BY, and ORDER BY clauses.

     CREATE INDEX idx_column ON table(column);
    

2. SELECT *

  • Why it’s slow: Fetching all columns increases I/O and memory usage unnecessarily.
  • How to optimize: Select only the needed columns.

     SELECT column1, column2 FROM table;
    

3. Too Many Joins

  • Why it’s slow: Complex joins over large tables can lead to inefficient execution plans.
  • How to optimize: Ensure proper indexing on join keys, reduce joins where possible, and denormalize data for frequent queries.

     SELECT * FROM table1 
     JOIN table2 ON table1.id = table2.foreign_id;
    

4. LIKE with Leading Wildcards

  • Why it’s slow: Using LIKE '%value' leads to a full table scan.
  • How to optimize: Use full-text search or avoid leading wildcards.

     SELECT * FROM table WHERE column LIKE 'value%';
    

5. Functions on Indexed Columns

  • Why it’s slow: Applying functions to indexed columns disables index usage.
  • How to optimize: Avoid applying functions to indexed columns in the WHERE clause.

     SELECT * FROM table WHERE DATE(column) = '2023-09-05';
     -- Optimization:
     SELECT * FROM table WHERE column >= '2023-09-05 00:00:00' AND column <= '2023-09-05 23:59:59';
    

6. Too Many Subqueries

  • Why it’s slow: Subqueries are often inefficient and require repeated scanning.
  • How to optimize: Replace subqueries with JOIN or WITH (CTE - Common Table Expressions).

     WITH cte AS (SELECT ...) 
     SELECT * FROM cte JOIN another_table;
    

7. Non-SARGable Queries

  • Why it’s slow: Queries that prevent the use of indexes (non-SARGable) by performing operations on indexed columns.
  • How to optimize: Write queries that allow index utilization (SARGable).

     SELECT * FROM table WHERE column + 1 = 10;
     -- Optimization:
     SELECT * FROM table WHERE column = 9;
    

8. Inefficient Pagination (OFFSET)

  • Why it’s slow: Using OFFSET causes the database to scan and discard rows.
  • How to optimize: Use "keyset pagination" or "seek method."

     -- Slow pagination:
     SELECT * FROM table ORDER BY column LIMIT 10 OFFSET 1000;
     -- Optimization:
     SELECT * FROM table WHERE id > last_seen_id ORDER BY column LIMIT 10;
    

9. OR in WHERE Clause

  • Why it’s slow: Queries with OR prevent index optimization.
  • How to optimize: Use UNION ALL or rewrite the query to avoid OR.

     SELECT * FROM table WHERE column1 = 'value1' OR column2 = 'value2';
     -- Optimization:
     SELECT * FROM table WHERE column1 = 'value1'
     UNION ALL
     SELECT * FROM table WHERE column2 = 'value2';
    

10. Unnecessary Sorting (ORDER BY)

  • Why it’s slow: Sorting large result sets is expensive.
  • How to optimize: Avoid ORDER BY unless absolutely necessary and ensure the column is indexed.

     SELECT * FROM table ORDER BY column;
    

11. DISTINCT Overuse

  • Why it’s slow: DISTINCT forces SQL to perform additional sorting and comparison.
  • How to optimize: Ensure no duplicates are generated in the first place, and avoid unnecessary use of DISTINCT.

     SELECT DISTINCT column FROM table;
    

12. Inefficient Use of IN

  • Why it’s slow: Large IN lists cause inefficient scanning.
  • How to optimize: Use a JOIN or a subquery instead of large IN clauses.

     SELECT * FROM table WHERE column IN (SELECT ...);
    

13. JOIN Without Indexing

  • Why it’s slow: Joining tables without indexes on the join columns forces full table scans.
  • How to optimize: Always index the columns used in joins.

     SELECT * FROM table1 JOIN table2 ON table1.column = table2.column;
    

14. GROUP BY on Large Tables

  • Why it’s slow: GROUP BY can be slow on large tables without proper indexing.
  • How to optimize: Index the columns used in GROUP BY.

     SELECT column, COUNT(*) FROM table GROUP BY column;
    

15. HAVING Without WHERE

  • Why it’s slow: HAVING filters after aggregation, which leads to unnecessary computations.
  • How to optimize: Use WHERE for pre-aggregation filtering.

     SELECT column, COUNT(*) FROM table HAVING COUNT(*) > 1;
     -- Optimization:
     SELECT column, COUNT(*) FROM table WHERE condition GROUP BY column;
    

16. Unnecessary UNION Instead of UNION ALL

  • Why it’s slow: UNION removes duplicates, which is more expensive than UNION ALL.
  • How to optimize: Use UNION ALL if duplicates are not an issue.

     SELECT * FROM table1 UNION ALL SELECT * FROM table2;
    

17. Inefficient UPDATE Statements

  • Why it’s slow: Updating large numbers of rows without conditions can lock large parts of the table.
  • How to optimize: Use batch updates or filter updates.

     UPDATE table SET column = value WHERE condition LIMIT 1000;
    

18. Too Many Transactions

  • Why it’s slow: Holding transactions open for too long locks resources.
  • How to optimize: Keep transactions as short as possible.

     BEGIN TRANSACTION;
     UPDATE ...;
     COMMIT;
    

19. Not Using Connection Pooling

  • Why it’s slow: Creating new connections for each query is costly.
  • How to optimize: Implement connection pooling to reuse existing connections.

20. Data Type Mismatch

  • Why it’s slow: SQL engines have to convert data types during comparisons.
  • How to optimize: Ensure consistent data types between columns and literals.

     SELECT * FROM table WHERE varchar_column = 123;
     -- Optimization:
     SELECT * FROM table WHERE varchar_column = '123';
    

When to Use and When Not to Use These Optimizations

Use These Optimizations When:

  • Performance Degrades: When queries slow down with increasing data volume, optimizing becomes necessary to maintain application performance.
  • Frequent Queries: If a query runs frequently (e.g., part of an API), optimizing it will have a bigger impact.
  • Resource Constraints: On limited systems (CPU, memory, or disk), optimizations are critical to avoid resource exhaustion.
  • Scalability Is Required: As your database grows, query optimization ensures the system scales effectively.

Avoid These Optimizations When:

  • Premature Optimization: If the query runs fast on current data and system resources are not being exhausted, there may be no need for optimization. Focus on actual bottlenecks.
  • Small Datasets: For small datasets, optimizations like adding indexes might have little to no benefit and could even increase complexity unnecessarily.
  • Readability Over Performance: In cases where query performance is adequate, readability may take precedence, especially in complex queries where splitting joins or refactoring queries could reduce maintainability.

In summary, understanding both when and how to optimize SQL queries can significantly improve performance without over-complicating your codebase. Balance between optimization and simplicity is key to maintainable and efficient applications.

Top comments (0)