top of page

SQL Server Query Tips for Database Performance. How to improve SQL Query Performance?

Updated: Jan 25

Efficient and speedy data retrieval is crucial for the success of applications and systems that rely on database. SQL (Structured Query Language) is a powerful tool for managing and querying database, but poorly optimized SQL queries can lead to sluggish performance and increased response times. To ensure your database performs at its best, it's essential to focus on improving SQL query performance. This article will provide you with practical tips and best practices to enhance the performance of your SQL queries. By implementing these strategies, you can optimize the execution of your queries, reduce processing times, and create a more responsive and efficient database environment.

How to improve SQL Query performance

SQL Server is a relational database management system (RDBMS) developed and marketed by Microsoft. It is built on top of SQL, a standard programming language for interacting with relational database. SQL Server uses Transact-SQL (T-SQL), which is Microsoft's implementation of SQL and includes proprietary programming constructs.


SQL Server Query Tips for Database Performance:

Here are some SQL tips to improve SQL query performance:


1. Use SELECT fields instead of using SELECT *

Instead of using "SELECT *" to fetch all columns from a table, specify the specific fields you need. This reduces unnecessary data retrieval and improves query performance.

Example: Inefficient:

SELECT * FROM Customers 

Efficient:

SELECT FirstName, LastName, Address, City, State FROM Customers 


2. Avoid using SELECT DISTINCT

SELECT DISTINCT is useful for removing duplicate records but can be resource-intensive. Instead, select more fields to create unique results without using SELECT DISTINCT.

Example: Inefficient and inaccurate:

SELECT DISTINCT FirstName, LastName, State 
FROM Customers 

Efficient and accurate:

SELECT FirstName, LastName, Address, City, State 
FROM Customers 

3. Create joins with INNER JOIN (not WHERE)

Use INNER JOIN syntax for joining tables instead of using WHERE clauses. Joining with WHERE can lead to Cartesian Joins, which generate unnecessary combinations of records. INNER JOIN ensures only the desired records are joined.

Example: Inefficient:

SELECT Customers.CustomerID, Customers.Name, Sales.LastSaleDate 
FROM Customers, Sales 
WHERE Customers.CustomerID = Sales.CustomerID 

Efficient:

SELECT Customers.CustomerID, Customers.Name, Sales.LastSaleDate 
FROM Customers 
INNER JOIN Sales ON Customers.CustomerID = Sales.CustomerID 


4. Use WHERE instead of HAVING to define filters

Use WHERE clauses to filter records based on conditions instead of HAVING. WHERE clauses are evaluated before grouping, resulting in better query optimization.

Example: Inefficient:

SELECT Customers.CustomerID, Customers.Name, Count(Sales.SalesID) 
FROM Customers 
INNER JOIN Sales ON Customers.CustomerID = Sales.CustomerID 
GROUP BY Customers.CustomerID, Customers.Name 
HAVING Sales.LastSaleDate BETWEEN '2016-01-01' AND '2016-12-31'

Efficient:

SELECT Customers.CustomerID, Customers.Name, Count(Sales.SalesID) 
FROM Customers 
INNER JOIN Sales ON Customers.CustomerID = Sales.CustomerID 
WHERE Sales.LastSaleDate BETWEEN '2016-01-01' AND '2016-12-31'
GROUP BY Customers.CustomerID, Customers.Name 


5. Use wildcards at the end of a phrase only

When using wildcards with LIKE for searching plaintext data, place the wildcard at the end of the phrase. Leading wildcards or using them at both ends can result in inefficient searches.

Example: Inefficient:

SELECT City FROM Customers 
WHERE City LIKE '%Char%'

Efficient:

SELECT City FROM Customers 
WHERE City LIKE 'Char%'

These tips focus on writing efficient queries. Additionally, improving query performance in SQL Server involves considerations such as index creation, understanding data characteristics, and eliminating unnecessary cursors.


How to Improve SQL Query Performance

Here are some tips to improve SQL query performance:


1. Avoid Multiple Joins in a Single Query: Try to minimize the use of multiple joins that include outer joins, cross apply, outer apply, and complex subqueries. Excessively complex queries limit the optimizer's choices for determining the join order and type, often resulting in suboptimal performance, such as the forced use of nested loop joins.


2. Eliminate Cursors from the Query: Replace cursors with set-based queries whenever possible. Set-based queries are more efficient than cursor-based operations. If you must use a cursor, avoid dynamic cursors as they limit the query optimizer's plan choices. For instance, using a dynamic cursor restricts the optimizer to use nested loop joins.


3. Avoid Non-correlated Scalar Subqueries: Rewrite queries to remove non-correlated scalar subqueries from the main query. Instead, execute them separately and store the results in variables. You can then refer to these variables in the main query or later in the batch. This approach provides better optimization options, resulting in accurate cardinality estimates and improved query plans.


4. Avoid Multi-statement Table-Valued Functions (TVFs): Multi-statement TVFs are costlier than inline TVFs. While SQL Server expands inline TVFs into the main query, treating them like views, it evaluates multi-statement TVFs separately, creating temporary work tables for their results. This separate context and work table usage make multi-statement TVFs less efficient.


5. Creation and Use of Indexes: Indexes can significantly improve data retrieval time, but they may have a reverse effect on data modification operations (DML), potentially impacting query performance. Indexing is a challenging task, but it can enhance SQL query performance and provide better response times. Consider the trade-offs between query performance and DML operations when creating indexes.


6. Understand the Data: Gain a thorough understanding of the data, its type, and the query patterns used to retrieve it before creating indexes. Understanding the data behavior helps in making informed decisions about choosing clustered or non-clustered indexes. If a clustered index is not on a unique column, SQL Server maintains uniqueness by adding a unique identifier to each duplicate key, resulting in overhead. Select the appropriate column or make necessary changes to avoid such overhead.


7. Create a Highly Selective Index: Selectivity refers to the percentage of qualifying rows in a table (qualifying rows/total rows). Highly selective indexes are most useful when the ratio of qualifying rows to total rows is low, such as around 5% or less. A non-clustered index that can eliminate 95% of the rows from consideration is particularly valuable. If an index returns more than 5% of the rows in a table, it may not be used, and an alternative index or table scan will be chosen.


8. Position a Column in an Index: The order or position of a column in an index is crucial for improving SQL query performance. If the query criteria match the leftmost columns in the index key, the index can effectively enhance query performance. As a best practice, place the most selective columns leftmost in the key of a non-clustered index.


9. Drop Unused Indexes: Removing unused indexes can speed up data modification operations without affecting data retrieval. Define a strategy for batch processes that run infrequently and rely on specific indexes. Create the necessary indexes in advance of the batch processes and drop them when the processes are completed. This approach helps reduce the overhead on the database.


That's It!

1 comment
bottom of page