Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql T-SQL插入-表变量中的Select非常慢_Tsql_Variables_Select_Insert - Fatal编程技术网

Tsql T-SQL插入-表变量中的Select非常慢

Tsql T-SQL插入-表变量中的Select非常慢,tsql,variables,select,insert,Tsql,Variables,Select,Insert,我有一个表变量,使用Insert Into-Select语句在其中插入一些值。select是几个连接的组合,单独执行时需要3秒钟。问题是整个代码需要3-4分钟才能执行。我想知道这有什么特别的原因 这是my table变量声明: DECLARE @Result TABLE ( ProductID NVARCHAR(25) PRIMARY KEY ,ProductName NVARCHAR(100) ,ProductCategoryID TINYINT ,Prod

我有一个表变量,使用Insert Into-Select语句在其中插入一些值。select是几个连接的组合,单独执行时需要3秒钟。问题是整个代码需要3-4分钟才能执行。我想知道这有什么特别的原因

这是my table变量声明:

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 @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秒钟,否则会花费很长时间

编辑:这是我的执行计划-大部分成本是表扫描,但为什么在插入时要花费这么多时间,而没有插入时又恰好是quick

下面是我的新内联函数:

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

我又慢跑了。如何优化它?插入表变量的查询不能有并行计划


尝试使用临时表,以允许并行选择。

使用查询分析器的“解释计划”按钮显示时间的位置。@JeffWatkins我将在我的问题上附上带有执行计划的屏幕截图。如果选择临时表,会发生什么情况?@MarkRobinson你是指临时表吗?@marc_,是的,这解决了我的问题。@Joro-你能把它改写成一个内联TVF而不是多语句TVF吗?这样就完全不需要插入中间表变量。这意味着您将查询重写为单个语句。使用CTE或派生表替换@TempTable@MartinSmith我可以使用任何类型的函数,但我认为返回表的唯一方法是这个?@Joro-不,有两种不同类型的TVF。内联语句的效率更高,因为它们被优化程序内联,但需要在单个SQL语句中表达逻辑。@MartinSmith是的,谢谢,我明白了。我会这样做的。再次感谢。@Joro-。因此,使用CTEProtoSurveyID,ProductID作为选择不同的TOP 2147483647 CASTB.ProtoSurveyID作为INT,CASTA.Col002作为NVARCHAR25 FROM。。。B.ProtoSurveyID订购