1

最初のクエリはサーバー上で実行するのに 10 秒以上かかり、2 つ目のクエリは 1 秒未満で実行されるため、以下の 2 つのクエリの違いは何だろうと思っていました...

更新 - 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

最初のクエリの実行プラン

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

ここに画像の説明を入力

ただし、クエリの速度または最適化の問題は解決しましたが、最初のクエリが2番目のクエリに変換されると思っていたので、これら2つのクエリの違いが正確に何であるかについて興味がありました...

UPDATE - I ご覧のとおり、両方のクエリは、INステートメントに変換されたJOINSのみが異なります...

4

2 に答える 2

2

たとえば、最初のステートメントはとテーブルの両方から一致するすべてのレコードを取得しますが、2 番目のステートメントは から一致するすべての行のみを取得します。ProductsCategoryProducts

最初のステートメントを次のように変更した場合のパフォーマンスの違いは何ですか?

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

編集

(マーティンが述べたように)テーブルCatNo内で一意の場合、行数は両方のステートメントでのみ同一であることに注意してください。ステートメントは、テーブル内の一意のレコードと同じ数のレコードを返しCategoryますINNER JOINが、Categoryテーブル内のレコードと同じ数のレコードを返します。INCatNoCategory

于 2012-05-30T06:12:35.397 に答える
0

in 句は、product から返される行をフィルター処理します。内部結合は、カテゴリから選択ステートメントの出力に列を追加します。

于 2012-05-30T06:13:16.243 に答える