1

次の名前のテーブルがあります。

mktActualsales (SaleID, EmployeeID, PeriodID,PositionID)
 mktActualSalesItems(SaleItemID, saleID, Item, Quantity)
 mktSalesTargets(TargetID, EmployeeID, PeriodID,PositionID)
 mktSalesTargetItems(TargetITemID, TargetID,ItemID, Quantity )
 sysPeriods(PeriodID, StartDate, EndDate) 

上記のテーブル間の関係は明らかです。sale と saleDetails は SaleID を介して関連付けられ、Target と TargetDetail は TargetID を介して関連付けられます。表示したいのは全期間の従業員の売上と目標です。売上がない期間もあれば、目標が達成されない期間もあります。

それを行う私の計画 (これまでのところ) は、1 つのサブクエリで sales と saleDetail の内部結合を取得し、別のサブクエリで target と targetDetail を取得し、両方のサブクエリで完全な外部結合を実行して、必要なデータを取得することです。しかし、結果は非常に遅いです。パフォーマンスを高速化するために私ができること。完全外部結合とユニオンオールのパフォーマンス比較のためにグーグルで検索しましたが、運がありませんでした。現時点では、Union/Union All を使用して目的の結果を達成できるかどうかはわかりません。

編集

これは私がこれまでに持っているクエリです。テーブルも編集

SELECT  sale.ActualSaleID, 
        COALESCE (sale.EmployeeID, saleTarget.EmployeeID) AS EmployeeID, 
        COALESCE (sale.PositionID, saleTarget.PositionID) AS PositionID, 
        COALESCE (sale.PeriodID, saleTarget.PeriodID) AS PeriodID, 
        COALESCE (sale.SKUID, saleTarget.SKUID) AS SKUID, 
        COALESCE (sale.SalesQuantity, 0) AS SalesQuantity, 
        saleTarget.SalesTargetID, 
        COALESCE (saleTarget.TargetQuantity, 0) AS TargetQuantity, 
        saleTarget.SalesTargetItemID, 
        sale.ActualSaleItemID, 
        p.StartDate, 
        p.EndDate
FROM (
        SELECT  s.ActualSaleID, 
                s.EmployeeID, 
                s.PeriodID, 
                s.PositionID, 
                si.ActualSaleItemID, 
                si.SKUID, 
                si.SalesQuantity
        FROM dbo.mktActualSaleItems AS si 
            INNER JOIN dbo.mktActualSales AS s 
                ON si.ActualSaleID = s.ActualSaleID
    ) AS sale 
    FULL OUTER JOIN
    (
        SELECT  t.EmployeeID, 
                t.PeriodID, 
                t.PositionID, 
                t.SalesTargetID, 
                ti.SKUID, 
                ti.TargetQuantity, 
                ti.SalesTargetItemID
        FROM dbo.mktSalesTargetItems AS ti 
            INNER JOIN dbo.mktSalesTargets AS t 
                ON t.SalesTargetID = ti.SalesTargetID
    ) AS saleTarget 
        ON sale.PeriodID = saleTarget.PeriodID 
        AND sale.PositionID = saleTarget.PositionID 
        AND sale.SKUID = saleTarget.SKUID 
    INNER JOIN dbo.sysPeriods AS p 
        ON p.PeriodID = COALESCE (sale.PeriodID, saleTarget.PeriodID)
4

2 に答える 2

1

サブクエリは必要ないと思います。1 つのクエリで同じことができます

SELECT  s.ActualSaleID, 
        COALESCE (s.EmployeeID, t.EmployeeID) AS EmployeeID, 
        COALESCE (s.PositionID, t.PositionID) AS PositionID, 
        COALESCE (s.PeriodID, t.PeriodID) AS PeriodID, 
        COALESCE (si.SKUID, ti.SKUID) AS SKUID, 
        COALESCE (si.Quantity, 0) AS SalesQuantity, 
        t.TargetID, 
        COALESCE (ti.Quantity, 0) AS TargetQuantity, 
        ti.TargetITemID, 
        si.SaleItemID, 
        p.StartDate, 
        p.EndDate
FROM dbo.mktActualSales AS s 
        INNER JOIN dbo.mktActualSaleItems AS si 
            ON si.ActualSaleID = s.ActualSaleID
    FULL OUTER JOIN dbo.mktSalesTargets AS t 
        ON s.PeriodID = t.PeriodID 
        AND s.PositionID = t.PositionID 
        AND si.SKUID = ti.SKUID 
            INNER JOIN dbo.mktSalesTargetItems AS ti 
                ON t.SalesTargetID = ti.SalesTargetID
    INNER JOIN dbo.sysPeriods AS p 
        ON p.PeriodID = COALESCE (s.PeriodID, t.PeriodID)

フィールドの命名についてはよくわかりませんが、アイデアはわかります。

これにより、クエリが高速化される場合があります。

インデックスも忘れずにチェック!!

于 2011-06-17T08:17:33.943 に答える
1

クエリにバグがあると思います。SALE と SALETARGET の結合に employeeID 列が含まれていません。COALESCE はそれを隠しますが、必要以上に多くの行を取得していると思います...

ただし、クエリを高速化する方法は、そもそもクエリが遅い理由を突き止めることです。実行計画は進むべき道です。クエリ アナライザーを使用して、何が起こっているかを確認します。すべての結合のインデックスにヒットしていますか? 現在の実装ですべてのオプションを使い果たした場合にのみ、union ステートメントを使用するようにクエリを書き直してください。

スタイルの問題として、結合する列に COALESCE を使用する必要はないと思います.そもそも null にすることはできず、バグを隠す傾向があります.

于 2011-06-17T09:01:13.567 に答える