High CPU or memory grants may occur with queries that use optimized nested loop or batch sort
This article helps you resolve the problem where high CPU usage occurs when you run queries in SQL Server.
Applies to: SQL Server
Original KB number: 2009160
Symptoms
When you operate Microsoft SQL Server that has a highly concurrent workload, you may notice some performance issues in queries. This behavior may exhibit as medium to high CPU usage or extreme memory grant requests.
You may also experience other side effects, such as OOM conditions, memory pressure for plan cache eviction, or unexpected RESOURCE_SEMAPHORE
waits.
Additionally, you may notice that query plans for queries that consume lots of CPU or memories have the OPTIMIZED attribute for a Nested Loops join operator set to True.
Cause
This issue may occur in some cases where SQL Server query processor introduces an optional sort operation to improve performance. This operation is known as an "Optimized Nested Loop" or "Batch Sort" and the query optimizer determines when to best introduce these operators. In rare cases, the query touches only a few rows, but the setup cost for the sort operation is so significant that the cost of the optimized nested loop outweighs its benefits. Therefore, in those cases you may observe slower performance compared to what is expected.
Resolution
Trace flag 2340
To fix the issue, use trace flag 2340 to disable the optimization. Trace flag 2340 instructs the query processor not to use a sort operation (batch sort) for optimized nested loop joins when generating a query plan. This affects the entire instance.
Before you enable this trace flag, you can test your applications thoroughly to make sure that you get the expected performance benefits when you disable this optimization. This is because the sort optimization can be helpful when there is a large increase in the number of rows that are touched by the plan.
For more information, see DBCC TRACEON - Trace Flags (Transact-SQL).
Modify code to use the DISABLE_OPTIMIZED_NESTED_LOOP hint
Alternatively, apply the following DISABLE_OPTIMIZED_NESTED_LOOP
query hint to disable the optimization at the query level.
SELECT * FROM Person.Address
WHERE City = 'SEATTLE' AND PostalCode = 98104
OPTION (USE HINT (DISABLE_OPTIMIZED_NESTED_LOOP));
For more information, see DISABLE_OPTIMIZED_NESTED_LOOP.
More information
Database Engine Service Startup Options
Applies to
- SQL Server 2005 through SQL Server 2019