具有估计行数的表值参数1

时间:2014-04-16 21:19:38

标签: sql sql-server-2008 sql-execution-plan table-valued-parameters

我一直在网上搜索数小时,试图找出如何使用表值参数(TVP)来提高查询性能。

经过几个小时的搜索,我终于确定了我认为是问题的根源。在检查了我的查询的估计执行计划后,我发现每次使用TVP时,我的查询的估计行数为1。如果我将TVP交换为选择我感兴趣的数据的查询,则估计的行数在7400左右更准确。这显着提高了性能。

然而,在真实场景中,我无法使用查询,我必须使用TVP。有没有办法让SQL Server在使用TVP时更准确地预测行数,以便使用更合适的计划?

1 个答案:

答案 0 :(得分:4)

TVP是表变量,它不保持统计数据,因此报告只有1行。有两种方法可以改善TVP的统计数据:

  1. 如果您不需要修改TVP中的任何值或向其添加列来跟踪操作数据,那么您可以对任何使用的查询执行简单的语句级OPTION (RECOMPILE)表变量(TVP或本地创建的)并且使用该表变量比简单的SELECT做更多(即执行INSERT INTO RealTable (columns) SELECT (columns) FROM @TVP;不需要语句级重新编译)。在SSMS中执行以下测试以查看此行为:

    DECLARE @TableVariable TABLE (Col1 INT NOT NULL);
    
    INSERT INTO @TableVariable (Col1)
      SELECT so.[object_id]
      FROM   [master].[sys].[objects] so;
    
    -- Control-M to turn on "Include Actual Execution Plan"
    
    SELECT * FROM @TableVariable; -- Estimated Number of Rows = 1 (incorrect)
    
    SELECT * FROM @TableVariable
    OPTION (RECOMPILE); -- Estimated Number of Rows = 91 (correct)
    
    SELECT * FROM @TableVariable; -- Estimated Number of Rows = 1 (back to incorrect)
    
  2. 创建一个本地临时表(单#)并将TVP数据复制到该表。虽然这确实会复制tempdb中的数据,但其好处是:

    • 更好的临时表统计信息而不是表变量(即不需要语句级重新编译)
    • 添加列的能力
    • 修改值的能力