zoukankan      html  css  js  c++  java
  • 《SQL Server 2005技术内幕:TSQL查询》上的一处错误

    SQL Server 2005技术内幕:T-SQL查询》一书的第7章,“使用TOPApply解决常见问题”一节中,介绍了多种方式获得每个销售员的最新订单。

    其中第三种方式是这样的。书上只是说这是个“糟糕计划”,其实是糟糕T-SQL代码造成的。而这个方案其实可以优化成为作者给出的三个用于SQL Server 2000的方案中最好的一个。

    SELECT OrderID, CustomerID, E.EmployeeID, OrderDate, RequiredDate
    FROM dbo.Employees AS E
       
    JOIN dbo.Orders AS O1
         
    ON OrderID IN
           (
    SELECT TOP(3) OrderID
            
    FROM dbo.Orders AS O2
            
    WHERE O2.EmployeeID = E.EmployeeID
            
    ORDER BY OrderDate DESC, OrderID DESC);

    有看出问题吗?再看看它上面的图。


    注意第二个
    Nested Loops上有一个感叹号。知道是什么原因了吗?如果还没有看出问题的话,可以参考书上271页,讲述联接的部分。 

    这个警告是“没有联接谓词”,说明白些,就是指上面的SQL代码中的JOIN没有相关的ON子句。注意不是说没有ON子句,是说没有与JOIN相关的ON子句。 

    没有ON子句的JOIN就变成了CROSS JOIN。能不慢吗? 

    大家有兴趣可以自己想一想如何优化这个SQL。我在AdventureWorks上做的测试,运行速度提高近100倍。 

    答案如下: 

    SELECT OrderID, CustomerID, E.EmployeeID, OrderDate, RequiredDate
    FROM dbo.Employees AS E
       
    JOIN dbo.Orders AS O1
         
    ON O1.EmployeeID = E.EmployeeID AND OrderID IN
           (
    SELECT TOP(3) OrderID
            
    FROM dbo.Orders AS O2
            
    WHERE O2.EmployeeID = E.EmployeeID
            
    ORDER BY OrderDate DESC, OrderID DESC);

    其执行计划如下图所示:


    书中有错误是很正常的。读一本书,其实可以把找出错误的个数,作为衡量书是不是真正读懂的一个标准。我自己读书就有一个习惯,把书的第一个空白页当勘误表。一般发现翻译错误、字词遗漏什么的也不值当发上来,不过这个错误感觉就比较严重了。

  • 相关阅读:
    cs231n.stanford.edu
    cs229.stanford.edu
    Boost circular_buffer example
    OI中一些常见实用的套路【更新中】
    用Java读取xml文件内容
    在控制台中操作MYSQL数据库步骤以及一些小问题
    java 实现对指定目录的文件进行下载
    将java项目发布到本地的linux虚拟机上
    mybatis 控制台打印出来的sql 执行结果为空 但是将sql放到mysql执行有数据
    spring mvc 拦截器
  • 原文地址:https://www.cnblogs.com/nankezhishi/p/insidetsqlqueryerror.html
Copyright © 2011-2022 走看看