Frontend
Still Writing Slow SQL Queries? 10 Ways to Improve Performance
qodors DEV Community
2 views
A SQL query can return the right data and still do much more work than it needs to. A query that works well with a small dataset may become slow as the application grows.
When a query starts taking longer, developers often try adding an index, changing a JOIN, or increasing server resources. Those changes can help, but they do not always address the actual problem. The first step should be finding out what the database is really doing.
The SQL query optimizer uses the query, indexes, statistics, joins, filters, and estimated costs to choose an execution plan. Good query design gives the optimizer a better chance of choosing an efficient plan.
Here are 10 practical ways to find and fix common SQL performance problems.
1. Check the Execution Plan First
Before changing a slow query, look at its execution plan.
The plan can show whether the database is scanning a large table, using an index, performing an expensive join, or spending most of its time on a particular operation.
For example:
SELECT *
FROM Orders
WHERE CustomerId = 1024;
The query looks simple. But the execution plan can tell you whether the database is finding the matching rows efficiently or scanning the whole table.
Instead of guessing what might be wrong, start by looking at the actual work being done.
2. Avoid SELECT*
Only request the columns the application needs.
Instead of:
SELECT *
FROM Customers
WHERE Country = 'India';
use:
SELECT CustomerId, Name, Email
FROM Customers
WHERE Country = 'India';
Returning unnecessary columns means more data may need to be read, processed, and sent back to the application.
This matters even more when a table contains large text fields, JSON data, or other wide columns.
3. Use Indexes for Frequent Filters
Indexes can make a big difference when they match the way your application searches or sorts data.
For example:
SELECT OrderId, OrderDate
FROM Orders
WHERE CustomerId = 1024;
If CustomerId is frequently used for filtering, an appropriate index can help the database find the required rows without scanning the entire table.
But adding indexes to every column is not a solution. Indexes use storage and also add work when rows are inserted, updated, or deleted.
Create indexes around real query patterns and then check the execution plan to see whether they actually help.
4. Be Careful With Functions in WHERE Conditions
Using a function on a column in a filter can sometimes make efficient index usage more difficult.
For example:
SELECT *
FROM Orders
WHERE YEAR(OrderDate) = 2026;
A range condition can give the database a better opportunity to use an index:
SELECT *
FROM Orders
WHERE OrderDate >= '2026-01-01'
AND OrderDate < '2027-01-01';
This does not mean the second query will always be faster. The result depends on the database engine, indexes, and data.
Check the execution plan and measure both versions before making the change.
5. Optimize JOIN Conditions
Joins are a normal part of application queries, but they can become expensive when large amounts of data are involved.
For example:
SELECT o.OrderId, c.Name
FROM Orders o
JOIN Customers c
ON o.CustomerId = c.CustomerId;
The columns used for the join should be appropriate for the database design and indexing strategy. Also check whether the join is actually needed.
Filters can help reduce the amount of data that has to be processed. A query may become expensive when the database works through thousands of unnecessary rows even though only a few rows are returned.
6. Limit the Data You Return
Sometimes the database query itself is not the main problem. The application may simply be asking for too much data.
For a search page, there is usually no reason to return every matching record at once. Pagination keeps the result size manageable.
For example, SQL Server supports OFFSET/FETCH:
SELECT ProductId, Name, Price
FROM Products
ORDER BY ProductId
OFFSET 0 ROWS
FETCH NEXT 50 ROWS ONLY;
The right pagination approach depends on the database, indexes, and application requirements.
The basic idea is simple: if the user needs 50 records, do not make the database process and transfer thousands of records unnecessarily.
7. Keep Statistics Up to Date
The optimizer uses statistics about data distribution when it chooses an execution plan.
When those statistics are outdated, the optimizer may estimate the number of matching rows incorrectly. It might expect a query to return a few rows when the actual result contains millions.
That kind of incorrect estimate can lead to a poor execution plan.
Keeping statistics up to date is especially important for tables where data changes frequently. Database maintenance should be part of the overall performance strategy.
8. Watch Out for N+1 Queries
A query can be fast by itself and still cause a serious performance problem when the application runs it hundreds or thousands of times.
Imagine an application loading 1,000 customers first. It then runs another query for each customer to retrieve their orders.
Instead of making one efficient database operation, the application creates a large number of database round trips.
Look for ways to retrieve related data through joins, batching, or carefully designed queries.
N+1 problems are common in APIs and applications that use ORMs because the database calls may be hidden behind application code.
9. Review Subqueries and Complex Conditions
A complex query is not automatically a bad query. But when a query contains several subqueries, nested conditions, OR expressions, joins, or aggregations, it is worth looking closely at the execution plan.
For example:
SELECT *
FROM Products
WHERE CategoryId IN (
SELECT CategoryId
FROM Categories
WHERE IsActive = 1
);
Another possible approach is:
SELECT p.*
FROM Products p
JOIN Categories c
ON p.CategoryId = c.CategoryId
WHERE c.IsActive = 1;
Changing an IN subquery to a JOIN does not automatically make the query faster.
The database engine, optimizer, indexes, and amount of data all affect the result. Test both versions and compare their execution plans before deciding which one is better for your workload.
10. Measure Before and After the Change
Query optimization should always end with measurement.
Suppose a query takes four seconds and a new index brings it down to 500 milliseconds. That looks like a clear improvement. But the index also uses storage and may make inserts or updates more expensive.
For important changes, compare things such as:
Execution time
Logical reads
CPU usage
Number of rows processed
Execution plans
This gives you a clearer picture of whether the change actually improved the workload.
Database performance is not just about making one query look better. A change that improves one query can sometimes create another problem elsewhere.
Our Take
At Qodors, we have seen developers rewrite SQL queries before checking what is actually slowing them down.
The SQL query optimizer already evaluates the query and chooses an execution strategy. Instead of trying to work around it, make sure it has the right indexes, updated statistics, clear queries, and realistic data to work with.
Start by checking the execution plan. From there, review the indexes and statistics, look for unnecessary data, check your joins, and watch for repeated database calls.
Then measure the change.
A shorter or cleaner query is not always faster. A more complex query is not necessarily slower either. The execution plan and actual performance tell you what is really happening.
For SQL performance work, use the data to guide your decisions instead of guessing.
Quick Reference
Check the execution plan before changing a slow query.
Avoid SELECT * when you only need specific columns.
Create indexes based on real query patterns.
Be careful when using functions on filtered columns.
Review expensive joins on large tables.
Return only the data the application needs.
Keep database statistics up to date.
Watch for N+1 query patterns.
Test alternative query structures instead of assuming one is faster.
Measure performance before and after important changes.
Do not optimize SQL by guessing. Find where the database is spending its time, make one focused change, and measure what happens.
SQL #SQLServer #Database #DatabasePerformance #SQLQuery #QueryOptimization #SQLPerformance #Backend #BackendDevelopment #QodorsEdge
Read original: https://dev.to/qodors/still-writing-slow-sql-queries-10-ways-to-improve-performance-3hho
← Previous
Your AI Coding Agent Needs a Dependency Graph, Not Just a Repository
Next →
Dead Code Is More Dangerous Than Broken Code — How a Non-Homologous AI Caught the Blind Spot the AI Itself Had Rubber-Stamped
Related
n8n Error Workflows Can Send Failure Alerts, but Runs Are Not Universally Free
Frontend
1
DEV Community
How a hidden timer measures your sense of time with millisecond precision
Frontend
1
DEV Community
I Stopped Writing Accessibility Reports by Hand
Frontend
2
DEV Community
How to make this pill background align with the actual button text?
Frontend
3
Reddit r/webdev
Comments0
No comments yet — be the first