Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.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
Sql 估计行数为1的表值参数_Sql_Sql Server 2008_Sql Execution Plan_Table Valued Parameters - Fatal编程技术网

Sql 估计行数为1的表值参数

Sql 估计行数为1的表值参数,sql,sql-server-2008,sql-execution-plan,table-valued-parameters,Sql,Sql Server 2008,Sql Execution Plan,Table Valued Parameters,我在互联网上搜索了几个小时,试图找出如何使用表值参数TVP来提高查询的性能 经过数小时的搜索,我终于确定了我认为问题的根源。在检查查询的估计执行计划时,我发现每当我使用TVP时,查询的估计行数都是1。如果我用TVP交换一个选择我感兴趣的数据的查询,那么估计的行数更准确,大约为7400行。这将显著提高性能 然而,在真实场景中,我不能使用查询,我必须使用TVP。有没有办法让SQL Server在使用TVP时更准确地预测行数,以便使用更合适的计划?TVP是不维护统计信息的表变量,因此报表只有一行。有两

我在互联网上搜索了几个小时,试图找出如何使用表值参数TVP来提高查询的性能

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


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

TVP是不维护统计信息的表变量,因此报表只有一行。有两种方法可以改进TVP的统计数据:

如果不需要修改TVP中的任何值或向其添加列以跟踪操作数据,则可以执行简单的,语句级选项在使用表变量TVP或本地创建的任何查询上重新编译,并且使用该表变量比使用简单的SELECT执行更多操作,即执行INSERT INTO RETABLE columns FROM@TVP选择列;不需要语句级重新编译。在SSMS中执行以下测试以查看此行为的作用:

创建一个本地临时表,并将TVP数据复制到该表中。虽然这会复制tempdb中的数据,但其好处是:

与表变量相比,temp表具有更好的统计特性,即不需要语句级重新编译 添加列的能力 修改值的能力
能否对表值变量使用更新统计信息。@Dannyg9090否,临时变量不存储统计信息。重新编译真的解决了估计问题吗?TVPs没有统计信息。@usr是的,语句级重新编译确实为该查询获取了正确的行数。由于不维护表变量的统计信息,因此很遗憾,行计数不会被带到引用该表变量的后续查询中。我已经用一个测试更新了我的答案,测试结果表明它是有效的。@usr是的,这里有一篇艾伦·伯特兰写的很棒的文章
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)