1

我想知道下面提到的两个查询之间有什么区别,因为第一个查询在服务器上执行需要 10 多秒,而第二个查询在不到一秒的时间内执行......

更新 - 我 这里是从 SQL Server 复制和粘贴的实际查询及其执行计划(原样),对于我以前的查询造成的任何不便,我深表歉意...... :(

SELECT  REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-') AS ManagmentPlanDate
FROM    ManagmentPlan m
        INNER JOIN Product p ON p.Product_ID = m.ProductID
        INNER JOIN Category c ON c.C_ID = p.C_ID
        LEFT OUTER JOIN Employee e ON e.emp_no = m.PrescribedBy
        LEFT OUTER JOIN dbo.Issue_Stock i ON i.serial_no = m.IssueStockID
        INNER JOIN dbo.Units u ON u.U_ID = p.U_ID
WHERE   ( ( @PatientID IS NULL )
          AND ( @VisitID IS NULL )
          AND ( m.WardRegNo = @WardRegNo )
        )
        OR --Get only cuurent admission TP 
        ( ( @PatientID IS NULL )
          AND ( @WardRegNo IS NULL )
          AND ( VisitID = @VisitID
                AND m.WardRegNo IS NULL
              )
        )
        OR -- Get Only Current OPD visit TP 
        ( ( @WardRegNo IS NULL )
          AND ( @VisitID IS NULL )
          AND ( visitid IN ( SELECT id
                             FROM   PatientVisit
                             WHERE  PatientID = @PatientID ) )
        )
        OR --Get All Visits TP
        ( ( @PatientID IS NULL )
          AND ( @VisitID IS NOT NULL )
          AND ( @WardRegNo IS NOT NULL )
          AND ( ( VisitID = @VisitID )
                OR ( m.WardRegNo = @WardRegNo )
              )
        ) -- Get Current OPD visit and cuurent admission TP (Both)
        AND m.Deleted != 1
        AND m.PatientDeptID = @PatientDeptID
GROUP BY REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-')
ORDER BY CAST(REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-') AS DATETIME) DESC

第一个Query的执行计划

SELECT  REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-') AS ManagmentPlanDate
FROM    ManagmentPlan m
WHERE   m.ProductID IN ( SELECT Product_ID
                         FROM   Product
                         WHERE  C_ID IN ( SELECT    C_ID
                                          FROM      Category )
                                AND U_ID IN ( SELECT    U_ID
                                              FROM      Units ) )
        AND m.PrescribedBy IN ( SELECT  Emp_no
                                FROM    Employee )
        AND m.IssueStockID IN ( SELECT  Serial_No
                                FROM    Issue_Stock )
        AND ( ( @PatientID IS NULL )
              AND ( @VisitID IS NULL )
              AND ( m.WardRegNo = @WardRegNo )
            )
        OR --Get only cuurent admission TP 
        ( ( @PatientID IS NULL )
          AND ( @WardRegNo IS NULL )
          AND ( VisitID = @VisitID
                AND m.WardRegNo IS NULL
              )
        )
        OR -- Get Only Current OPD visit TP 
        ( ( @WardRegNo IS NULL )
          AND ( @VisitID IS NULL )
          AND ( visitid IN ( SELECT id
                             FROM   PatientVisit
                             WHERE  PatientID = @PatientID ) )
        )
        OR --Get All Visits TP
        ( ( @PatientID IS NULL )
          AND ( @VisitID IS NOT NULL )
          AND ( @WardRegNo IS NOT NULL )
          AND ( ( VisitID = @VisitID )
                OR ( m.WardRegNo = @WardRegNo )
              )
        ) -- Get Current OPD visit and cuurent admission TP (Both)
        AND m.Deleted != 1
        AND m.PatientDeptID = @PatientDeptID
GROUP BY REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-')
ORDER BY CAST(REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-') AS DATETIME) DESC

在此处输入图像描述

虽然,它解决了我的查询速度或优化问题,但只是好奇这两个查询之间到底有什么区别,因为我认为第一个查询转换为第二个查询......

UPDATE - I 如您所见,这两个查询的不同之处仅在于将JOINS转换为IN语句...

4

2 回答 2

2

首先,您的第一个语句从表中检索所有匹配的记录,ProductsCategory您的第二个语句仅从Products.

如果您将第一个语句更改为

SELECT p.*
FROM   Products p
       INNER JOIN Category c ON p.CatNo = c.CatNo

编辑

(如 Martin 所述)请注意,如果CatNoCategory表中是唯一的,则两个语句的行数仅相同。将INNER JOIN返回与表中一样多的记录,Category而语句将返回与表中唯一的IN记录一样多的记录。CatNoCategory

于 2012-05-30T06:12:35.397 回答
0

in 子句过滤从产品返回的行。内连接将列从类别添加到选择语句输出。

于 2012-05-30T06:13:16.243 回答