5

そのため、スピードアップする必要があるSPでいくつかの非常に遅いクエリがあり、OPTIMIZE FOR UNKNOWNを使用しており、パフォーマンスが劇的に向上しています。本当に遅いクエリがまだ 1 つあり、これを適用したいのですが、2 つの SQL クエリの UNION が含まれているので、両方に OPTIMIZE FOR UNKNOWN を適用しますか?

これは、わかりやすくするために私の SP を大幅に簡略化したものです。

SELECT * FROM MyTable ManufacturerID=@ManufacturerID and tStamp > @tStamp
OPTION (OPTIMIZE FOR (@ManufacturerID UNKNOWN, @tStamp UNKNOWN)) 
UNION
SELECT * FROM MyTable ManufacturerID=@ManufacturerID
OPTION (OPTIMIZE FOR (@ManufacturerID UNKNOWN) 

現在の実際の SP は次のとおりです。

SELECT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY Products.ItemID) AS RowNum, *
    FROM
    (
    SELECT  Products.ProductID, Products.ItemID, Products.ManufacturerID,
          CategoryID = NULL, CategoryName = NULL, 
          CategoryProductID = NULL,  Products.ItemName, Products.Description, Products.Notes, 
                      Products.Dimensions, Products.BasePrice, Products.OrderMinimumQuantity, 
                      ContainerMinimumQuantity = 
                        CASE  COALESCE(Products.ContainerMinQty, 0)
                            WHEN 0 THEN Products.OrderMinimumQuantity
                            ELSE Products.ContainerMinQty
                        END 
                      , Products.OrderMultipleQuantity, Products.OnHandQuantity, 
                      Products.Category, Products.IntroDate, Products.BackOrderDate, Products.UPC, Products.PriceLevel1, Products.PriceLevel2, Products.PriceLevel3, 
                      Products.PriceLevel4, Products.PriceLevel5, Products.PriceLevel6, Products.PriceLevel7, Products.PriceLevel8, Products.PriceLevel9, Products.PieceBox, 
                      Products.Cubes, Products.UnitOfMeasure, Products.UDF1, Products.UDF2, Products.UDF3, Products.UDF4, Products.UDF5, Products.AdditionalImageCount, 
                     PhotoName= LOWER(Products.PhotoName),  Products.Discontinued, Products.ModifiedOn, 
                        Products.IsDeleted, Products.PriceLevel10, Products.PriceLevel11, Products.PriceLevel12, Products.PriceLevel13, 
                      Products.PriceLevel14, Products.PriceLevel15, Products.PriceLevel16, Products.PriceLevel17, Products.PriceLevel18, Products.PriceLevel19, Products.PriceLevel20, 
                      Products.Weight, Products.DimensionsMetric, Products.Source, Products.InventoryStatus, Products.CatalogCode, Products.CatalogName, 
                       SortOrder = NULL,
                       Products.reportCategory,Products.additionalPhotos,Products.udf6,Products.udf7,Products.udf8,
                       Products.udf9,Products.udf10,Products.udf11,Products.udf12,Products.udf13,Products.udf14,Products.udf15,Products.udf16,
                       Products.udf17,Products.udf18,Products.udf19,Products.udf20, Products.showRelatedFor,Products.showChildFor
FROM    
CategoryProducts (nolock) RIGHT OUTER JOIN
                      Products (nolock) ON CategoryProducts.ManufacturerID = Products.ManufacturerID AND CategoryProducts.ItemID = Products.ItemID
WHERE     (Products.ManufacturerID = @ManufacturerID)
            AND 
            (Products.ModifiedOn > @tStamp ) AND  ((CategoryProducts.IsDeleted = 1) OR (CategoryProducts.IsDeleted IS NULL)
            )

            UNION

            SELECT Products.ProductID, Products.ItemID, Products.ManufacturerID, Categories.CategoryID, Categories.CategoryName, CategoryProducts.CategoryProductID,  Products.ItemName, Products.Description, Products.Notes, 
                      Products.Dimensions, Products.BasePrice, Products.OrderMinimumQuantity, 
                      ContainerMinimumQuantity = 
                        CASE  COALESCE(Products.ContainerMinQty, 0)
                            WHEN 0 THEN Products.OrderMinimumQuantity
                            ELSE Products.ContainerMinQty
                        END 
                      , Products.OrderMultipleQuantity, Products.OnHandQuantity, 
                      Products.Category, Products.IntroDate, Products.BackOrderDate, Products.UPC, Products.PriceLevel1, Products.PriceLevel2, Products.PriceLevel3, 
                      Products.PriceLevel4, Products.PriceLevel5, Products.PriceLevel6, Products.PriceLevel7, Products.PriceLevel8, Products.PriceLevel9, Products.PieceBox, 
                      Products.Cubes, Products.UnitOfMeasure, Products.UDF1, Products.UDF2, Products.UDF3, Products.UDF4, Products.UDF5, Products.AdditionalImageCount, 
                     PhotoName= LOWER(Products.PhotoName),  Products.Discontinued, Products.ModifiedOn, 
                        CategoryProducts.IsDeleted, Products.PriceLevel10, Products.PriceLevel11, Products.PriceLevel12, Products.PriceLevel13, 
                      Products.PriceLevel14, Products.PriceLevel15, Products.PriceLevel16, Products.PriceLevel17, Products.PriceLevel18, Products.PriceLevel19, Products.PriceLevel20, 
                      Products.Weight, Products.DimensionsMetric, Products.Source, Products.InventoryStatus, Products.CatalogCode, Products.CatalogName, 
                       CategoryProducts.SortOrder,
                       Products.reportCategory,Products.additionalPhotos,Products.udf6,Products.udf7,Products.udf8,
                       Products.udf9,Products.udf10,Products.udf11,Products.udf12,Products.udf13,Products.udf14,Products.udf15,Products.udf16,
                       Products.udf17,Products.udf18,Products.udf19,Products.udf20, Products.showRelatedFor,Products.showChildFor
FROM      Categories (nolock) INNER JOIN
                      CategoryProducts (nolock) ON Categories.CategoryID = CategoryProducts.CategoryID INNER JOIN
                      Products (nolock) ON CategoryProducts.ManufacturerID = Products.ManufacturerID AND CategoryProducts.ItemID = Products.ItemID
WHERE     (Products.ManufacturerID = @ManufacturerID)
            AND 
            (Products.ModifiedOn > @tStamp OR  CategoryProducts.ModifiedOn > @tStamp)
            )  AS Products
        ) AS C  WHERE RowNum >= @StartRow AND RowNum <= @EndRow ORDER BY ItemID, ManufacturerID
    OPTION (OPTIMIZE FOR (@ManufacturerID UNKNOWN, @StartRow UNKNOWN, @EndRow UNKNOWN, @tStamp UNKNOWN)) 
4

2 に答える 2

3

オンライン ブックから (クエリ ヒント):

クエリ ヒントは、示されたヒントがクエリ全体で使用される必要があることを指定します。これらはステートメント内のすべての演算子に影響します。UNION がメイン クエリに含まれる場合、UNION 操作を含む最後のクエリのみが OPTION 句を持つことができます。

OPTIONしたがって、例のように2回ではなく、1回しか使用できないことは明らかです。

2 つのSELECTステートメントがまとめられていても、SQL Server はコンパイルと最適化のために 1 つの全体的なステートメントとして扱います。

これは、 を構成するさまざまなステートメントでさまざまなヒントを使用したい場合UNION、別の方法で実行する必要があることを意味します。たとえば、一時的な結果を保存するために TEMP テーブルを使用するなどです。

したがって、特定の例で@tStampは、最初のステートメントにのみ含まれていますが、必要に応じて 1 つの句SELECTで参照できます。OPTION

于 2013-06-28T14:36:07.257 に答える
1

これを試してみてください -

SELECT
      p.ProductID
    , RowNum = ROW_NUMBER() OVER(ORDER BY p.ItemID) 
    , p.ItemID
    , p.ManufacturerID
    , CategoryID = NULL
    , CategoryName = NULL
    , CategoryProductID = NULL
    , p.ItemName
    , p.[Description]
    , p.Notes
    , p.Dimensions
    , p.BasePrice
    , p.OrderMinimumQuantity
    , ContainerMinimumQuantity =
          CASE WHEN ISNULL(p.ContainerMinQty, 0) = 0
               THEN p.OrderMinimumQuantity ELSE p.ContainerMinQty
          END
    , p.OrderMultipleQuantity
    , p.OnHandQuantity
    , p.category
    , p.IntroDate
    , p.BackOrderDate
    , p.UPC
    ...
    , p.PieceBox
    , p.Cubes
    , p.UnitOfMeasure
    , p.UDF1, p.UDF2, p.UDF3
    , p.UDF4, p.UDF5
    , p.AdditionalImageCount
    , PhotoName = LOWER(p.PhotoName)
    , p.Discontinued
    , p.ModifiedOn
    , p.IsDeleted
    ...
    , p.[Weight]
    , p.DimensionsMetric
    , p.[Source]
    , p.InventoryStatus
    , p.CatalogCode
    , p.CatalogName
    , SortOrder = NULL
    , p.reportCategory
    , p.additionalPhotos
    ....
    , p.showRelatedFor
    , p.showChildFor
FROM dbo.Products p WITH(NOLOCK)
--LEFT JOIN (
--     SELECT *
--     FROM dbo.CategoryProducts cp WITH(NOLOCK)
--     WHERE ISNULL(cp.IsDeleted, 1) = 1
--) cp ON cp.ManufacturerID = p.ManufacturerID AND cp.ItemID = p.ItemID
WHERE p.ManufacturerID = @ManufacturerID
     AND p.ModifiedOn > @tStamp
于 2013-07-01T05:18:14.983 に答える