与没有存储过程的CTE相比,为什么存储过程中的CTE需要很长时间?

时间:2015-09-04 19:40:09

标签: sql-server stored-procedures common-table-expression

我有一个递归CTE,用于计算组织中的经理层次结构。

以下查询采用< 2秒完成

WITH OrganisationChart ([Identity], [DisplayName], Title, [Level], Manager) AS
(
      SELECT
            [Identity], [DisplayName], Title, 0, Manager
      FROM
            [data].[DailyUserV1] 
      WHERE 
            [Identity] = '7276DB4F-33B0-4074-9903-D95D740A8BF3' AND Date = '2015-08-03'

      UNION ALL 

      SELECT
            emp.[Identity], 
            emp.[DisplayName], 
            emp.Title, 
            [Level] + 1, 
            emp.Manager
      FROM
          [data].[DailyUserV1]  emp 
      INNER JOIN 
          OrganisationChart ON emp.Manager = OrganisationChart.[Identity]
      WHERE 
          Date = '2015-08-03'
)
SELECT * FROM OrganisationChart

虽然包含在存储过程中的同一查询采用> 15分钟,然后超时!

IF (OBJECT_ID('[dbo].[GetOrganizationChart]') IS NOT NULL)
   DROP PROCEDURE [dbo].[GetOrganizationChart]
GO

CREATE PROCEDURE [dbo].[GetOrganizationChart]
     @identity varchar(256),
     @date datetime
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE @userId varchar(256);
    SET @userId = @identity;

    DECLARE @endDate datetime;
    SET @endDate = @date;

    WITH OrganisationChart ([Identity], [DisplayName], Title, [Level], Manager) AS
    (
         SELECT
             [Identity], [DisplayName], Title, 0, Manager
         FROM
             [data].[DailyUserV1] 
         WHERE 
             [Identity] = @userId AND Date = @endDate

         UNION ALL 

         SELECT
             emp.[Identity], 
             emp.[DisplayName], 
             emp.Title, 
             [Level] + 1, 
             emp.Manager
         FROM
             [data].[DailyUserV1]  emp 
         INNER JOIN 
             OrganisationChart ON emp.Manager = OrganisationChart.[Identity]
         WHERE 
             Date = @endDate
    )
SELECT * FROM OrganisationChart;
END
GO

EXEC [dbo].[GetOrganizationChart] @identity = '7276DB4F-33B0-4074-9903-D95D740A8BF3', @date = '2015-08-03'

通过在存储过程中使用局部变量,我已经排除了参数嗅探的可能原因。这里发生了什么?

更新

以下是查询执行计划的链接,以供您查看。

cte-without-stored-proc cte-with-stored-proc

1 个答案:

答案 0 :(得分:1)

我之前遇到的同样问题是参数嗅探。为了克服这个问题,我使用临时表而不是CTE,SP开始顺利运行。