What are the best SQL Server Performance Tuning Optimization Tips

Microsoft SQL Server is a relational database management system, having MS-SQL and Transact-SQL as primary structured programming languages. They rely on relational algebra which is mainly used for data insertion, modifying, deletion and retrieval, as well as for data access controlling. The problem with getting the expected results is handled by the management system which has the purpose of finding the best execution plan, this process being called optimization. The most frequently used queries are those of data retrieval through SELECT command. We have to take into consideration that not only the select queries need optimization, but also other objects, such as: index, view or statistics.

How can you increase SQL performance?
How do you optimize SQL queries?
What is optimization in SQL?
How do you do performance tuning in SQL?
SQL Server Performance Tuning and Monitoring?


Apply proper indexing in the table columns in the database

Make sure that every table in your database has a primary key.
This will ensure that every table has a clustered index created (and hence, the corresponding pages of the table are physically sorted in the disk according to the primary key field). So, any data retrieval operation from the table using the primary key, or any sorting operation on the primary key field or any range of primary key values specified in the where clause will retrieve data from the table very fast.

Create non-clustered indexes on columns which are

Frequently used in the search criteria.

Used to join other tables.

Used as foreign key fields.

Of having high selectivity (column which returns a low percentage (0-5%) of rows from a total number of rows on a particular value).

Used in the ORDER BY clause.

Don't use "SELECT*" in a SQL query

Unnecessary columns may get fetched that will add expense to the data retrieval time. The database engine cannot utilize the benefit of "Covered Index" and hence the query performs slowly.

Example:

SELECT Cash, Age, Amount FROM Investments;

Instead of:

SELECT * FROM Investments;

Avoid HAVING Clause in Select statements

HAVING clause is used to filter the rows after all the rows are selected and is used like a filter. Try not to use HAVING clause for any other purposes.

Example:

SELECT Name, count (Name) FROM Investments WHERE Name!= ‘Test’ AND Name!= ‘Value’ GROUP BY Name;

Instead of:

SELECT Name, count (Name) FROM Investments GROUP BY Name HAVING Name!= ‘Test’ AND Name!= ‘Value’ ;

Minimize number of sub query blocks within a query

Sometimes we may have more than one sub query in our main query. We should try to minimize the number of sub query block in our query.

Example:

SELECT Amount FROM Investments WHERE (Cash, Fixed) = (SELECT MAX (Cash), MAX (Fixed) FROM Retirements) AND Goal = 1;

Instead of:

SELECT Amount FROM Investments WHERE Cash = (SELECT MAX (Cash) FROM Retirements) AND Fixed = (SELECT MAX (Fixed) FROM Retirements) AND Goal = 1;
Avoid unnecessary columns in the SELECT list and unnecessary tables in join conditions

Selecting unnecessary columns in a Select query adds overhead to the actual query, especially if the unnecessary columns are of LOB types. Including unnecessary tables in join conditions forces the database engine to retrieve and fetch unnecessary data and increases the query execution time.

Do not use the COUNT() aggregate in a subquery to do an existence check

When you use COUNT(), SQL Server does not know that you are doing an existence check. It counts all matching values, either by doing a table scan or by scanning the smallest non-clustered index. When you use EXISTS, SQL Server knows you are doing an existence check. When it finds the first matching value, it returns TRUE and stops looking.

Avoid joining between two types of columns

When joining between two columns of different data types, one of the columns must be converted to the type of the other. The column whose type is lower is the one that is converted. If you are joining tables with incompatible types, one of them can use an index, but the query optimizer cannot choose an index on the column that it converts.

Use COUNT(*) to obtain the record count in a table

To get the total row count in a table, we usually use the following Select statement:

SELECT COUNT(*) FROM [dbo].[PercentageForGoal]
This query will perform a full table scan to get the row count. The following query would not require a full table scan. (Please note that this might not give you 100% perfect results always, but this is handy only if you don't need a perfect count.)

SELECT rows FROM sysindexes

WHERE id = OBJECT_ID('[dbo].[PercentageForGoal]') AND indid< 2

Use operators like EXISTS, IN and JOINS appropriately in your query

Usually IN has the slowest performance.

IN is efficient, only when most of the filter criteria for selection are placed in the sub-query of a SQL statement.

EXISTS is efficient when most of the filter criteria for selection is in the main query of a SQL statement.

Avoid dynamic SQL

Unless really required, try to avoid the use of dynamic SQL because: Dynamic SQL is hard to debug and troubleshoot. If the user provides the input to the dynamic SQL, then there is a possibility of SQL injection attacks.

Avoid the use of temporary tables

Unless really required, try to avoid the use of temporary tables. Rather use table variables. In 99% of cases, table variables reside in memory, hence it is a lot faster. Temporary tables reside in the TempDb database. So operating on temporary tables require inter database communication and hence will be slower.

Instead of LIKE search, use full text search for searching textual data

Full text searches always outperform LIKE searches. Full text searches will enable you to implement complex search criteria that can't be implemented using a LIKE search, such as searching on a single word or phrase (and optionally, ranking the result set), searching on a word or phrase close to another word or phrase, or searching on synonymous forms of a specific word. Implementing full text search is easier to implement than LIKE search (especially in the case of complex search requirements).

Use UNION to implement an "OR" operation

Try not to use "OR" in a query. Instead use "UNION" to combine the result set of two distinguished queries. This will improve query performance. Better use UNION ALL if a distinguished result is not required. UNION ALL is faster than UNION as it does not have to sort the result set to find out the distinguished values.

Implement a lazy loading strategy for large objects

Store Large Object columns (like VARCHAR(MAX), Image, Text etc.) in a different table than the main table, and put a reference to the large object in the main table. Retrieve all the main table data in a query, and if a large object is required to be loaded, retrieve the large object data from the large object table only when it is required.

Implement the following good practices in User Defined Functions

Do not call functions repeatedly within your Stored Procedures, triggers, functions, and batches. For example, you might need the length of a string variable in many places of your procedure, but don't call the LEN function whenever it's needed; instead, call the LEN function once, and store the result in a variable for later use.

Implement the following good practices in Triggers

Try to avoid the use of triggers. Firing a trigger and executing the triggering event is an expensive process.
Never use triggers that can be implemented using constraints.
Do not use the same trigger for different triggering events (Insert, Update and Delete).
Do not use transactional code inside a trigger. The trigger always runs within the transactional scope of the code that fires the trigger.


Post a Comment

Previous Post Next Post