8

テーブル変数があり、"Insert Into - Select" ステートメントを使用していくつかの値を挿入しています。select はいくつかの結合の組み合わせで、個別に実行すると 3 秒かかります。問題は、コード全体の実行に 3 ~ 4 分かかることです。これには特別な理由があるのだろうか。

これは私のテーブル変数宣言です:

DECLARE @Result TABLE 
(
     ProductID NVARCHAR(25) PRIMARY KEY
    ,ProductName NVARCHAR(100)
    ,ProductCategoryID TINYINT
    ,ProductCategory  NVARCHAR(50)
    ,ProductSubCategoryID TINYINT
    ,ProductSubCategory  NVARCHAR(50)
    ,BrandID TINYINT
    ,Brand  NVARCHAR(50)
)

いくつかのデータで初期化する他のテーブル変数があり、これがその構造です。

DECLARE @TempTable TABLE
(
    ProtoSurveyID INT,
    ProductID NVARCHAR(25) PRIMARY KEY
)

そして、次のコードは私の問題文です(insert into - select):

INSERT INTO @Result (ProductID,ProductName,ProductCategoryID,ProductCategory,ProductSubCategoryID,ProductSubCategory,BrandID,Brand)
SELECT 
         Products.ProductID  AS ProductID
        ,Products.ProductName  AS ProductName
        ,ProductCategories.ProductCategoryID  AS ProductCategoryID
        ,ProductCategories.ProductCategory   AS ProductCategory
        ,ProductSubCategories.ProductSubCategoryID  AS ProductSubCategoryID
        ,ProductSubCategories.ProductSubCategory  AS ProductSubCategory
        ,Brands.BrandID AS BrandID
        ,Brands.Brand  AS Brand
FROM 
(
        SELECT     
               CAST(A.Col001 AS tinyint) AS ProductCategoryID
              ,CAST(A.Col002 AS tinyint) AS BrandID
              ,CAST(A.Col003 AS nvarchar(25)) AS ProductID
              ,CAST(A.Col004 AS nvarchar(100)) AS ProductName
              ,CAST(A.Col006 As tinyint) AS ProductSubCategoryID
              ,B.ProtoSurveyID
        FROM DataSetsMaterializedDataSqlvariant A 
        INNER JOIN @TempTable B 
        ON B.ProductID=CAST(A.Col003 AS nvarchar(25))
        WHERE DataSetsMaterializedInternalRowsetID = 3 
) Products      
INNER JOIN
(
         SELECT CAST(A.Col001 AS tinyint) AS BrandID
              , CAST(A.Col002 AS nvarchar(50)) AS Brand
         FROM DataSetsMaterializedDataSqlvariant A
         WHERE DataSetsMaterializedInternalRowsetID = 1
)Brands On Products.BrandID=Brands.BrandID
INNER JOIN
(
         SELECT CAST(A.Col001 AS tinyint) AS ProductCategoryID
                ,CAST(A.Col002 AS nvarchar(50)) AS ProductCategory
         FROM DataSetsMaterializedDataSqlvariant A
         WHERE DataSetsMaterializedInternalRowsetID = 2
) ProductCategories On Products.ProductCategoryID=ProductCategories.ProductCategoryID
INNER JOIN
(
         SELECT CAST(A.Col001 AS tinyint) AS ProductSubCategoryID
              , CAST(A.Col002 AS nvarchar(50)) AS ProductSubCategory
         FROM DataSetsMaterializedDataSqlvariant A
         WHERE DataSetsMaterializedInternalRowsetID = 11
) ProductSubCategories on Products.ProductSubCategoryID=ProductSubCategories.ProductSubCategoryID

前に言ったように、挿入行にコメントを付けると、クエリに 3 秒かかります。それ以外の場合は、非常に長い時間がかかります。

編集:これが私の実行計画です-コストのほとんどはテーブルスキャンですが、挿入が行われるとなぜそんなに時間がかかり、それなしで速くなるのですか?

ここに画像の説明を入力

以下は、私の新しいインライン関数です。

CREATE FUNCTION [dbo].[fn_XxCustom_RetailAudits_GetProductsForFilter]
(
    @SecurityObjectUserID BIGINT
)
RETURNS TABLE
AS
RETURN

    WITH CTE(ProtoSurveyID,ProductID) AS
    (
        SELECT  DISTINCT  CAST(B.ProtoSurveyID AS INT)
                         ,CAST(A.Col002 AS NVARCHAR(25)) AS ProductID
        FROM DataSetsMaterializedDataSqlvariant A
        JOIN SurveyInstances B ON A.Col001=B.SurveyInstanceID AND CAST(B.ProtoSurveyID AS INT) IN (SELECT ProtoSurveyID FROM dbo.fn_Filter_GetProtoSurveysAllowedShort(@SecurityObjectUserID, 'CLIENTACCESS',NULL))
        WHERE DataSetsMaterializedInternalRowsetID = 5
    )
    SELECT 
             Products.ProductID  AS ProductID
            ,Products.ProductName  AS ProductName
            ,ProductCategories.ProductCategoryID  AS ProductCategoryID
            ,ProductCategories.ProductCategory   AS ProductCategory
            ,ProductSubCategories.ProductSubCategoryID  AS ProductSubCategoryID
            ,ProductSubCategories.ProductSubCategory  AS ProductSubCategory
            ,Brands.BrandID AS BrandID
            ,Brands.Brand  AS Brand
    FROM 
    (
            SELECT     
                   CAST(A.Col001 AS tinyint) AS ProductCategoryID
                  ,CAST(A.Col002 AS tinyint) AS BrandID
                  ,CAST(A.Col003 AS nvarchar(25)) AS ProductID
                  ,CAST(A.Col004 AS nvarchar(100)) AS ProductName
                  ,CAST(A.Col006 As tinyint) AS ProductSubCategoryID
                  ,B.ProtoSurveyID
            FROM CTE B
            INNER JOIN DataSetsMaterializedDataSqlvariant A 
            ON B.ProductID=CAST(A.Col003 AS nvarchar(25))
            WHERE DataSetsMaterializedInternalRowsetID = 3 
    ) Products      
    INNER JOIN
    (
             SELECT CAST(A.Col001 AS tinyint) AS BrandID
                   ,CAST(A.Col002 AS nvarchar(50)) AS Brand
             FROM DataSetsMaterializedDataSqlvariant A
             WHERE DataSetsMaterializedInternalRowsetID = 1
    )Brands On Products.BrandID=Brands.BrandID
    INNER JOIN
    (
             SELECT  CAST(A.Col001 AS tinyint) AS ProductCategoryID
                    ,CAST(A.Col002 AS nvarchar(50)) AS ProductCategory
             FROM DataSetsMaterializedDataSqlvariant A
             WHERE DataSetsMaterializedInternalRowsetID = 2
    ) ProductCategories On Products.ProductCategoryID=ProductCategories.ProductCategoryID
    INNER JOIN
    (
             SELECT  CAST(A.Col001 AS tinyint) AS ProductSubCategoryID
                    ,CAST(A.Col002 AS nvarchar(50)) AS ProductSubCategory
             FROM DataSetsMaterializedDataSqlvariant A
             WHERE DataSetsMaterializedInternalRowsetID = 11
    ) ProductSubCategories on Products.ProductSubCategoryID=ProductSubCategories.ProductSubCategoryID

GO

またゆっくり走ります。それを最適化する方法はありますか?

4

1 に答える 1

11

テーブル変数に挿入するクエリは、並列プランを持つことができません。

を並列#temp化できるように、代わりにテーブルを使用してみてください。SELECT

于 2012-06-05T14:57:24.887 に答える