SQL Server Optimization Tips - How to avoid performance problems caused by the query OR

Prior wrote a blog " SQL SERVER OR will result in the analysis on the index scan or a full table scan " , which describes the OR can cause a variety of cases full table scan or index scan, and how to optimize the query contains OR SQL statements in several ways, in fact, there are some ways to optimize this problem, here briefly.

 

As shown below, all of the following SQL statement appears such an approach, because the program query interface, there may be multiple input of search criteria, users often favor to occupy a part or query (business case, should not have details , everyone can understand), but there is no program is generated by judging different query SQL statement, but with a SQL get, regardless of the user did not fill JobNo this query, the following written in this way: the WHERE ISNULL ( @JobNo , '' ) = '' OR = @JobNo jobno can satisfy the condition, to implement logic functions. 

 

DECLARE @GenerateDateStart DATETIME ,
    @GenerateDateEnd DATETIME ,
    @JobNo NVARCHAR(200) ,
    @GkNo NVARCHAR(200);
SET @JobNo = 'PT19B030';
SET @GkNo = 'PV19-1-8050'; 
 
  SELECT    *
  FROM      [dbo].[GEW_UnitConsumption] AS A
            LEFT JOIN dbo.UnitConsumption_Relation AS B ON B.UsableFlag = 'Y'
                                                           AND A.GewUnitConsumptionId = B.RootUnitConsumptionID
  WHERE     ( ISNULL(@JobNo, '') = ''
              OR A.JobNo = @JobNo
            )
            AND ( ISNULL(@GkNo, '') = ''
                  OR A.GkNo = @GkNo
                );

 

In fact, if dynamically generated SQL statements based on the query conditions can indeed avoid the situation OR query conditions appear, but no dynamic SQL statements above statement is simple and easy to understand and cooked through, especially in the case of query conditions more. Can only say that their pros and cons. Here we do not discuss the merits of that strategy.

 

 

clip_image001

 

下面介绍一种技巧,如何避免OR引起的索引扫描或全表扫描问题。我们可以使用CASE WHEN改写一下这个SQL语句,就能避免OR引起的执行计划不走索引查找(Index Seek)的情况,如下所示:

 

DECLARE @GenerateDateStart DATETIME ,
    @GenerateDateEnd DATETIME ,
    @JobNo NVARCHAR(200) ,
    @GkNo NVARCHAR(200);
SET @JobNo = 'PT19B030';
SET @GkNo = 'PV19-1-8050'; 
 
 
SELECT  *
FROM    [dbo].[GEW_UnitConsumption] AS A
        LEFT JOIN dbo.UnitConsumption_Relation AS B ON B.UsableFlag = 'Y'
                                                       AND A.GewUnitConsumptionId = B.RootUnitConsumptionID
WHERE   CASE WHEN ISNULL(@JobNo, '') = '' THEN A.JobNo
             ELSE @JobNo
        END = JobNo
        AND CASE WHEN ISNULL(@GkNo, '') = '' THEN A.GkNo
                 ELSE GkNo
            END = @GkNo;

 

clip_image002

 

Test comparison found that performance improvement is obvious, of course, this optimization techniques have limitations, and can not solve all the OR due to performance issues (no silver bullet!). As shown below, for the following scenario, this technique can not help it!

 

 

SELECT * FROM TEST1 WHERE A=12 OR B=500

Guess you like

Origin www.cnblogs.com/kerrycode/p/11911998.html