问题
I have been searching the internet for hours trying to figure out how to improve the performance of my query using table-valued parameters (TVP).
After hours of searching, I finally determined what I believe is the root of the problem. Upon examining the Estimated Execution plan of my query, I discovered that the estimated number of rows for my query is 1 anytime I use a TVP. If I exchange the TVP for a query that selects the data I am interested in, then the estimated number of rows is much more accurate at around 7400. This significantly increases the performance.
However, in the real scenario, I cannot use a query, I must use a TVP. Is there any way to have SQL Server more accurately predict the number of rows when using a TVP so that a more appropriate plan will be used?
回答1:
TVPs are Table Variables which don't maintain statistics and hence report only have 1 row. There are two ways to improve statistics on TVPs:
If you have no need to modify any of the values in the TVP or add columns to it to track operational data, then you can do a simple, statement-level
OPTION (RECOMPILE)
on any query that uses a table variable (TVP or locally created) and is doing more with that table variable than a simple SELECT (i.e. doingINSERT INTO RealTable (columns) SELECT (columns) FROM @TVP;
does not need the statement-level recompile). Do the following test in SSMS to see this behavior in action: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)
Create a local temporary table (single
#
) and copy the TVP data to that. While this does duplicate the data intempdb
, the benefits are:- better statistics for a temp table as opposed to table variable (i.e. no need for statement-level recompiles)
- ability to add columns
- ability to modify values
来源:https://stackoverflow.com/questions/23120360/table-valued-parameters-with-estimated-number-of-rows-1