• SQL Server 逻辑转换


    使用 OR 逻辑是因为它符合人们的思维习惯。用使用 OR 逻辑的逻辑表达式来确定优先级和标识锚点行之后的行,也相当直观。
     
    但是,因为 SQL Server 优化器的工作方式,OR 逻辑在性能方面存在问题,特别是当一些被筛选的列上没有索引时。
    例如,考虑这样一个筛选器“col1=5 or col2=10”。如果分别在 col1 和 col2 上有单独的索引,优化器可以先在每个索引中筛选出行,然后再对两个结果执行索引交集运算(index intersection)运算。然而,如果只在其中一列上有索引,即使筛选器的选择性非常高,这个索引也没什么用。为了确定不满足第一个筛选条件的行是否满足第二个筛选条件,SQL server 还是需要扫描整个表。
     
    另一方面,AND 逻辑在性能上具有更好的潜力。每个表达式都会缩小结果集的范围。在一个索引上筛选出的行已经是最终要返回的行的超集。所以,被筛选列上的任何索引都可能会有潜在的利用价值。是否值得使用已有的索引,得由选择性来决定,但至少有使用的可能,例如,考虑筛选器“col1=5 and col2=10”。这时最佳索引是在这两个列上创建的组合索引。然后,如果只在其中一列上具有索引,而且选项也足够高,这已经足够了。SQL Server 可以通过这个索引筛选数据,然后查找这些行,检查它们是否也满足第二个条件。
     
     
    使用下面的逻辑来筛选行:
    orderdate>'20080506' or ( orderdate = '20080506' and orderid >11075 )
    等价于:
    orderdate>='20080506' and ( orderdate > '20080506' and orderid >11075 )
     
    --实验如下:
    IF OBJECT_ID('dbo.MyOrders') IS NOT NULL
      DROP TABLE dbo.MyOrders;
    GO
    SELECT * INTO dbo.MyOrders FROM Sales.Orders
    CREATE INDEX idx_dt ON dbo.MyOrders(orderdate);
     
    使用 or 逻辑运算符:
    SELECT orderid, orderdate, custid, empid
    FROM dbo.MyOrders
    WHERE orderdate > '20080506'
       OR (orderdate = '20080506' AND orderid > 11075);
     
     
    使用 and 逻辑运算符:
    SELECT orderid, orderdate, custid, empid
    FROM dbo.MyOrders
    WHERE orderdate >= '20080506'
      AND (orderdate > '20080506' OR orderid > 11075);
     
     
    创建了组合索引之后,效果更加
    CREATE INDEX idx_dt_oid ON dbo.MyOrders(orderdate, orderid);
     
     
    结论显而易见:
    《1》、与 OR 逻辑相比,SQL Server 对 AND 逻辑能进行更好的优化。同样,也能对其他逻辑表达式实现这种转换。
    《2》、另一个结论是最好在决定优先级的所有列上创建一个索引。但问题是在产品环境中,并不总是能做到这一点。
     
     
     
    不要停下前进的脚步,哪怕每天进步一点点!
  • 相关阅读:
    【东师软工】第二次成绩排行榜
    博客(懒得在cnblog移了)
    elementUI el-tree 修改无子项的样式
    流文件下载方法
    2.2.3 核心模块--理解.NetCore Configuration 配置管理
    Centos7下安装部署Asp.Net Core多版本依赖环境
    LADP认证接入
    Identity Server基础
    浅析DevOps中结合IAST的落地介绍
    从Leetcode的回文子串中学习动态规划和中心扩散法
  • 原文地址:https://www.cnblogs.com/LvanHades/p/4436007.html
Copyright © 2020-2023  润新知