DEV Community

Cover image for 🗄️ 30 Ways to Optimize Your SQL
Leapcell
Leapcell

Posted on

🗄️ 30 Ways to Optimize Your SQL

Cover

1. Choose Appropriate Indexes

Tips

Create suitable indexes (single-column, composite indexes, etc.) for columns frequently used in queries.

Example

Problematic SQL:

SELECT name FROM employees WHERE department_id = 10;
Enter fullscreen mode Exit fullscreen mode

Optimization: Create an index for department_id:

CREATE INDEX idx_department_id ON employees(department_id);
Enter fullscreen mode Exit fullscreen mode

2. Avoid Using SELECT *

Tips

Query only the required columns to reduce the amount of returned data.

Example

Problematic SQL:

SELECT * FROM employees WHERE department_id = 10;
Enter fullscreen mode Exit fullscreen mode

Optimization: Query only necessary columns:

SELECT name FROM employees WHERE department_id = 10;
Enter fullscreen mode Exit fullscreen mode

3. Prefer JOIN Over Subqueries

Tips

Subqueries are generally less efficient than JOINs.

Example

Problematic SQL:

SELECT name FROM employees WHERE department_id IN (SELECT id FROM departments WHERE location = 'New York');
Enter fullscreen mode Exit fullscreen mode

Optimization: Use JOIN instead of subquery:

SELECT e.name FROM employees e JOIN departments d ON e.department_id = d.id WHERE d.location = 'New York';
Enter fullscreen mode Exit fullscreen mode

4. Use EXPLAIN to Analyze Queries

Tips

Use EXPLAIN or EXPLAIN ANALYZE to view the execution plan of SQL queries and identify performance bottlenecks.

Example

EXPLAIN SELECT name FROM employees WHERE department_id = 10;
Enter fullscreen mode Exit fullscreen mode

5. Avoid Unnecessary ORDER BY Operations

Tips

ORDER BY consumes significant resources, especially for large datasets. Use it only when sorting is necessary.

Example

Problematic SQL:

SELECT name FROM employees WHERE department_id = 10 ORDER BY hire_date;
Enter fullscreen mode Exit fullscreen mode

Optimization: Remove ORDER BY if sorting is not needed.

6. Optimize Pagination Queries Using LIMIT

Tips

For pagination, use LIMIT. For queries with large offsets, optimize using indexes or caching.

Example

Problematic SQL:

SELECT name FROM employees ORDER BY hire_date LIMIT 100000, 10;
Enter fullscreen mode Exit fullscreen mode

Optimization: Use primary keys or indexes to improve pagination performance:

SELECT name FROM employees WHERE id > 100000 ORDER BY hire_date LIMIT 10;
Enter fullscreen mode Exit fullscreen mode

7. Avoid Using Functions in WHERE Clauses

Tips

Function calls prevent index usage; avoid them where possible.

Example

Problematic SQL:

SELECT name FROM employees WHERE YEAR(hire_date) = 2023;
Enter fullscreen mode Exit fullscreen mode

Optimization: Use range queries instead:

SELECT name FROM employees WHERE hire_date BETWEEN '2023-01-01' AND '2023-12-31';
Enter fullscreen mode Exit fullscreen mode

8. Choose Proper Order for Composite Indexes

Tips

In composite indexes, place the column with higher selectivity first.

Example

For the query:

SELECT * FROM employees WHERE department_id = 10 AND status = 'active';
Enter fullscreen mode Exit fullscreen mode

Create an index with status first for better selectivity:

CREATE INDEX idx_status_department ON employees(status, department_id);
Enter fullscreen mode Exit fullscreen mode

9. Use Batch Inserts Instead of Single Inserts

Tips

Batch inserts significantly reduce I/O and locking overhead.

Example

Problematic SQL: Insert records one by one:

INSERT INTO employees (name, department_id) VALUES ('John', 10);
Enter fullscreen mode Exit fullscreen mode

Optimization: Use batch inserts:

INSERT INTO employees (name, department_id) VALUES ('John', 10), ('Alice', 20), ('Bob', 30);
Enter fullscreen mode Exit fullscreen mode

10. Avoid Using NOT IN

Tips

NOT IN has poor performance; replace it with NOT EXISTS or LEFT JOIN.

Example

Problematic SQL:

SELECT name FROM employees WHERE department_id NOT IN (SELECT id FROM departments);
Enter fullscreen mode Exit fullscreen mode

Optimization: Use LEFT JOIN:

SELECT e.name FROM employees e LEFT JOIN departments d ON e.department_id = d.id WHERE d.id IS NULL;
Enter fullscreen mode Exit fullscreen mode

11. Avoid Redundant DISTINCT

Tips

Use DISTINCT only when duplicate data needs removal.

Example

Problematic SQL:

SELECT DISTINCT name FROM employees WHERE department_id = 10;
Enter fullscreen mode Exit fullscreen mode

Optimization: Remove DISTINCT if duplicates are unnecessary.

12. Use Appropriate Join Types

Tips

Prefer INNER JOIN unless all data is required. Avoid LEFT JOIN or RIGHT JOIN unnecessarily.

Example

Problematic SQL:

SELECT e.name, d.name FROM employees e LEFT JOIN departments d ON e.department_id = d.id;
Enter fullscreen mode Exit fullscreen mode

Optimization: Use INNER JOIN:

SELECT e.name, d.name FROM employees e INNER JOIN departments d ON e.department_id = d.id;
Enter fullscreen mode Exit fullscreen mode

13. Use Table Partitioning

Tips

Partition large tables to improve query performance.

Example

CREATE TABLE employees (
    id INT,
    name VARCHAR(50),
    hire_date DATE
)
PARTITION BY RANGE (YEAR(hire_date)) (
    PARTITION p2020 VALUES LESS THAN (2021),
    PARTITION p2021 VALUES LESS THAN (2022)
);
Enter fullscreen mode Exit fullscreen mode

14. Optimize GROUP BY Queries

Tips

Optimize GROUP BY queries using indexes.

Example

SELECT department_id, COUNT(*) FROM employees GROUP BY department_id;
Enter fullscreen mode Exit fullscreen mode

15. Optimize IN Usage

Tips

For large IN operations, store data in temporary tables and use JOIN instead.

Example

Problematic SQL:

SELECT name FROM employees WHERE department_id IN (1, 2, 3, 4, 5);
Enter fullscreen mode Exit fullscreen mode

Optimization: Store IDs in a temporary table:

CREATE TEMPORARY TABLE temp_ids (id INT);
INSERT INTO temp_ids (id) VALUES (1), (2), (3), (4), (5);
SELECT e.name FROM employees e JOIN temp_ids t ON e.department_id = t.id;
Enter fullscreen mode Exit fullscreen mode

16. Limit the Use of Complex Views

Tips

Views add complexity and performance overhead. Use direct SQL for complex queries.

Example

Replace complex view queries with optimized SQL statements.

17. Optimize Lock Usage

Tips

Use appropriate locking mechanisms to avoid full-table locks (e.g., LOCK IN SHARE MODE).

Example

SELECT * FROM employees WHERE id = 10 FOR UPDATE;
Enter fullscreen mode Exit fullscreen mode

18. Optimize INSERT INTO SELECT Statements

Tips

Use indexes in INSERT INTO SELECT statements to improve performance.

Example

INSERT INTO employees_backup (id, name)
SELECT id, name FROM employees WHERE hire_date < '2020-01-01';
Enter fullscreen mode Exit fullscreen mode

19. Use Connection Pools

Tips

For frequent database operations, use connection pools to improve efficiency.

Example

Configure a connection pool at the application level.

20. Monitor and Adjust Memory Parameters

Tips

Adjust memory settings (e.g., MySQL’s innodb_buffer_pool_size) to match query demands.

Example

Tune configurations based on query memory requirements.

21. Optimize Distributed Queries

Tips

In distributed database environments, minimize cross-node data transfer and optimize query plans.

Example

Problematic SQL:

SELECT e.name, d.name
FROM employees e JOIN departments d
ON e.department_id = d.id
WHERE e.location = 'New York';
Enter fullscreen mode Exit fullscreen mode

Optimization: Process location-related data on the local node before global aggregation to avoid cross-node data transfer.

22. Multi-Column Index and Index Merging

Tips

When querying multiple columns, use composite indexes where possible. If not, the database may attempt index merging.

Example

Problematic SQL:

SELECT * FROM orders WHERE customer_id = 10 AND product_id = 5;
Enter fullscreen mode Exit fullscreen mode

Optimization: Combine indexes on customer_id and product_id for better performance. Use EXPLAIN to check if index merging is utilized.

23. Optimize Multi-Dimensional Analysis with CUBE and ROLLUP

Tips

Use CUBE and ROLLUP for multi-dimensional aggregation, reducing multiple GROUP BY queries.

Example

Problematic SQL: Multiple GROUP BY queries.

SELECT department_id, SUM(sales) FROM sales_data GROUP BY department_id;
SELECT region, SUM(sales) FROM sales_data GROUP BY region;
Enter fullscreen mode Exit fullscreen mode

Optimization: Use ROLLUP to aggregate at multiple levels:

SELECT department_id, region, SUM(sales)
FROM sales_data
GROUP BY department_id, region WITH ROLLUP;
Enter fullscreen mode Exit fullscreen mode

24. Use Window Functions for Complex Analysis Queries

Tips

Window functions (e.g., ROW_NUMBER(), RANK(), LAG(), LEAD()) simplify complex analysis, reducing the need for self-joins or subqueries.

Example

Problematic SQL: Self-join to fetch the previous record.

SELECT a.*,
       (SELECT sales FROM sales_data b WHERE b.id = a.id - 1) AS previous_sales
FROM sales_data a;
Enter fullscreen mode Exit fullscreen mode

Optimization: Use a window function:

SELECT id, sales, LAG(sales, 1) OVER (ORDER BY id) AS previous_sales
FROM sales_data;
Enter fullscreen mode Exit fullscreen mode

25. Partition Pruning for Large Tables

Tips

Use partition pruning to limit the data scan range for very large tables.

Example

Problematic SQL:

SELECT * FROM transactions WHERE transaction_date BETWEEN '2023-01-01' AND '2023-01-31';
Enter fullscreen mode Exit fullscreen mode

Optimization: Partition the table by date and leverage pruning:

CREATE TABLE transactions (
    id INT,
    amount DECIMAL(10, 2),
    transaction_date DATE
)
PARTITION BY RANGE (YEAR(transaction_date)) (
    PARTITION p2023 VALUES LESS THAN (2024)
);
Enter fullscreen mode Exit fullscreen mode

26. Minimize Temporary Table Usage

Tips

Reduce temporary table usage in complex queries as they increase disk I/O and impact performance.

Example

Problematic SQL: Using a temporary table to store intermediate results.

CREATE TEMPORARY TABLE temp_sales AS
SELECT department_id, SUM(sales) FROM sales_data GROUP BY department_id;
Enter fullscreen mode Exit fullscreen mode

Optimization: Use subqueries or Common Table Expressions (CTEs):

WITH temp_sales AS (
    SELECT department_id, SUM(sales) FROM sales_data GROUP BY department_id
)
SELECT * FROM temp_sales;
Enter fullscreen mode Exit fullscreen mode

27. Optimize Parallel Queries

Tips

Leverage parallel query execution for large datasets to improve efficiency.

Example

Problematic SQL: A large data scan without parallelism.

SELECT SUM(sales) FROM sales_data;
Enter fullscreen mode Exit fullscreen mode

Optimization: Enable parallel query execution:

ALTER SESSION ENABLE PARALLEL QUERY;
SELECT /*+ PARALLEL(sales_data, 4) */ SUM(sales) FROM sales_data;
Enter fullscreen mode Exit fullscreen mode

28. Accelerate Complex Queries with Materialized Views

Tips

For complex aggregation queries, use materialized views to store precomputed results.

Example

Problematic SQL: Complex aggregation query with performance bottlenecks.

SELECT department_id, SUM(sales) FROM sales_data GROUP BY department_id;
Enter fullscreen mode Exit fullscreen mode

Optimization: Create a materialized view:

CREATE MATERIALIZED VIEW mv_sales_data AS
SELECT department_id, SUM(sales) AS total_sales FROM sales_data GROUP BY department_id;
Enter fullscreen mode Exit fullscreen mode

29. Avoid Lock Contention to Optimize Concurrent Queries

Tips

In high-concurrency environments, avoid table or row locks by using appropriate locking mechanisms.

Example

Problematic SQL: Table lock causing performance degradation under high concurrency.

SELECT * FROM orders WHERE status = 'pending' FOR UPDATE;
Enter fullscreen mode Exit fullscreen mode

Optimization: Lock only specific rows:

SELECT * FROM orders WHERE order_id = 123 FOR UPDATE;
Enter fullscreen mode Exit fullscreen mode

30. Optimize Transactions by Reducing Locking Time

Tips

For long-running transactions, minimize locking time and reduce the scope of locks.

Example

Problematic SQL: Large-scale data operations locking tables during the transaction.

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;
Enter fullscreen mode Exit fullscreen mode

Optimization: Split into smaller transactions or reduce lock time:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
COMMIT;

BEGIN;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;
Enter fullscreen mode Exit fullscreen mode

Optimizing SQL queries is both an art and a science.

The techniques outlined above provide a robust foundation for improving query performance, but the key to true mastery lies in constant experimentation and adaptation.

Every database is unique - what works for one scenario may not work for another. Always analyze, test, and refine your queries to build your own optimization.


We are Leapcell, your top choice for deploying backend projects to the cloud.

Leapcell

Leapcell is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:

Multi-Language Support

  • Develop with Node.js, Python, Go, or Rust.

Deploy unlimited projects for free

  • pay only for usage — no requests, no charges.

Unbeatable Cost Efficiency

  • Pay-as-you-go with no idle charges.
  • Example: $25 supports 6.94M requests at a 60ms average response time.

Streamlined Developer Experience

  • Intuitive UI for effortless setup.
  • Fully automated CI/CD pipelines and GitOps integration.
  • Real-time metrics and logging for actionable insights.

Effortless Scalability and High Performance

  • Auto-scaling to handle high concurrency with ease.
  • Zero operational overhead — just focus on building.

Explore more in the Documentation!

Try Leapcell

Follow us on X: @LeapcellHQ


Read on our blog

Top comments (0)