我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SQL Server优化技巧——如何避免查询条件OR引起的性能问题

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SQL Server优化技巧——如何避免查询条件OR引起的性能问题

之前写过一篇博客SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析,里面介绍了OR可能会引起全表扫描或索引扫描的各种案例,以及如何优化查询条件中含有OR的SQL语句的几种方法,其实还有一些方法可以用来优化这种问题,这里简单介绍一下。

 

如下所示,下面的SQL语句之所有出现这种写法,是因为程序的查询界面,可能有多个输入性的查询条件,往往用户只填了一个或部分查询条件(业务情况,应该不用详细介绍,大家都能明白),但是程序里面没有通过判断查询条件生成不同的SQL语句,而是用一个SQL搞定,不管用户没有填写JobNo这个查询条件,下面这种写法:WHERE ISNULL(@JobNo, "") = ""  OR JobNo = @JobNo都能满足条件,实现逻辑功能。

 

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
                );

 

其实,如果根据查询条件动态生成SQL语句,的确能避免查询条件中出现OR的情形,但是动态SQL语句没有上面语句简单和通熟易懂,尤其是查询条件较多的情况下。只能说各有利弊。这里暂且不讨论那种策略的优劣。

 

 

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

 

测试对比发现性能改善非常明显,当然这种优化技巧也是有局限性的,并不能解决所有OR引起的性能问题(没有银弹!)。如下所示,对于下面这种情况,这种技巧也是无能为力!

 

 

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

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SQL Server优化技巧——如何避免查询条件OR引起的性能问题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SQL Server优化技巧——如何避免查询条件OR引起的性能问题

之前写过一篇博客“SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析”,里面介绍了OR可能会引起全表扫描或索引扫描的各种案例,以及如何优化查询条件中含有OR的SQL语句的几种方法,其实还有一些方法可以用来优化这种问题,这里简单介绍一下。   如下所示
SQL Server优化技巧——如何避免查询条件OR引起的性能问题
2017-06-21

编程热搜

目录