【问题标题】:SQL Server Execution Plan Actual Row Count Far Too Large For Simple SelectSQL Server 执行计划实际行数对于简单选择来说太大了
【发布时间】:2015-03-28 03:22:02
【问题描述】:

(长话短说 - 我认为奇怪的执行计划笔记列表中的第 3 位是问题所在)。

我目前遇到一个存储过程的性能非常糟糕,该存储过程在过去表现良好 - 这是在性能测试的上下文中,我们恢复数据库,然后对系统施加负载。我无法弄清楚我们系统的这一部分发生了什么变化。根据阻止报告,没有实质性的阻止(我们将阈值设置为 1 秒一段时间以检查这一点)。

通过捕获执行计划,我们发现 proc 中的单个查询是罪魁祸首。查询很简单

INSERT INTO #table (<columnset>)
SELECT <columnset> 
FROM table
WHERE <binary type column> > @binaryArgumentPassedIntoProc

对于源表:WHERE 子句中的时间戳列被索引。选择的列之一是 PK,并且是 varchar 类型。正在选择其他 3 个列(总共 5 个)。临时表没有索引/键或约束。

此表上的架构没有更改,只有一个小例外 - 源表上的一列现在将 TrimTrailingBlanks 设置为 yes。此列不在从中选择的列集中。我无法想象这很重要,但我想把它说出来。

当我恢复时间点时,我无法复制缓慢。在生产执行期间(意味着当它在性能测试环境中运行缓慢时)查询有时需要 30 多秒。在时间点备份中,查询耗时不到 1 秒。

通过比较从生产执行和时间点执行中捕获的执行计划数据,我看到了一些令人困惑的部分。请注意,查询(在这两种情况下)都会将 180 行插入到临时表中。

  1. 时间点备份执行中的 EstimatedRow 计数为 176.683。在生产执行中为 2。选择和插入也是如此
  2. select 的生产执行中的 TableCardinality 为 2,而在时间点执行中为 1578。这表明生产中的统计数据很糟糕,尽管我不确定当系统处于如此重的负载下时如何实时处理这个问题(执行期间表中实际上有 1578 行),这并不奇怪。话虽如此,在过去表现良好时,这不是问题。
  3. 执行计划中记录的插入临时表的实际行数在生产执行中列为 3222。在执行时间点,实际行数列为 180。

关于(3) - 我对Actual Number of Rows的理解是,它是迭代器在执行查询时调用GetNext()的次数。我认为通过简单的选择(主要是没有连接),实际行数值最多等于表中该点的行数(1578)。

最后,通过捕获物理和逻辑磁盘的性能计数器,它不喜欢有明显的磁盘排队,也不喜欢磁盘排队和缓慢执行之间的相关性。

有人对我如何进一步解决此问题有任何建议吗?

我们在 Windows Server 2008 R2 SP1 机器上运行 SQL Server 2008 R2。该机器有 16 个内核和 128 GB RAM(64 个专用于 SQL 服务器)。

更新:我在恢复之后和测试之前用数据播种了表,然后更新了统计信息并重新编译了程序。实际和预期的行数以及表基数反映了实际值,但我们仍然看到执行时间很长。

这是最新测试中的一个错误查询的 XML 显示计划配置文件统计跟踪事件输出:

<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.1" Build="10.50.2500.0"><BatchSequence><Batch><Statements><StmtSimple><QueryPlan DegreeOfParallelism="1" CachedPlanSize="24" CompileTime="4" CompileCPU="4" CompileMemory="192"><RelOp NodeId="0" PhysicalOp="Table Insert" LogicalOp="Insert" EstimateRows="170" EstimateIO="0.010254" EstimateCPU="0.00017" AvgRowSize="9" EstimatedTotalSubtreeCost="0.0154085" Parallel="0" EstimateRebinds="0" EstimateRewinds="0"><OutputList/><RunTimeInformation><RunTimeCountersPerThread Thread="0" ActualRows="69" ActualEndOfScans="1" ActualExecutions="1"/></RunTimeInformation><Update DMLRequestSort="0"><Object Database="[tempdb]" Schema="[dbo]" Table="[#sourceTable]"/><SetPredicate><ScalarOperator ScalarString="[#destinationTable].[record_Identifier] = RaiseIfNullInsert([Expr1008]),[#destinationTable].[modifiedTS] = [Expr1009],[#destinationTable].[Last_Update] = [DBName].[dbo].[sourceTable].[last_update],[#destinationTable].[LastValueUpdate] = [DBName].[dbo].[sourceTable].[LastValueUpdate],[#destinationTable].[OtherValue_lastUpdate] = [DBName].[dbo].[sourceTable].[OtherValue_lastUpdate]"><ScalarExpressionList><ScalarOperator><MultipleAssign><Assign><ColumnReference Table="[#destinationTable]" Column="record_Identifier"/><ScalarOperator><Intrinsic FunctionName="RaiseIfNullInsert"><ScalarOperator><Identifier><ColumnReference Column="Expr1008"/></Identifier></ScalarOperator></Intrinsic></ScalarOperator></Assign><Assign><ColumnReference Table="[#destinationTable]" Column="modifiedTS"/><ScalarOperator><Identifier><ColumnReference Column="Expr1009"/></Identifier></ScalarOperator></Assign><Assign><ColumnReference Table="[#destinationTable]" Column="Last_Update"/><ScalarOperator><Identifier><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="last_update"/></Identifier></ScalarOperator></Assign><Assign><ColumnReference Table="[#destinationTable]" Column="LastValueUpdate"/><ScalarOperator><Identifier><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="LastValueUpdate"/></Identifier></ScalarOperator></Assign><Assign><ColumnReference Table="[#destinationTable]" Column="OtherValue_lastUpdate"/><ScalarOperator><Identifier><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="OtherValue_lastUpdate"/></Identifier></ScalarOperator></Assign></MultipleAssign></ScalarOperator></ScalarExpressionList></ScalarOperator></SetPredicate><RelOp NodeId="1" PhysicalOp="Compute Scalar" LogicalOp="Compute Scalar" EstimateRows="170" EstimateIO="0" EstimateCPU="1.7e-005" AvgRowSize="50" EstimatedTotalSubtreeCost="0.00498448" Parallel="0" EstimateRebinds="0" EstimateRewinds="0"><OutputList><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="last_update"/><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="LastValueUpdate"/><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="OtherValue_lastUpdate"/><ColumnReference Column="Expr1008"/><ColumnReference Column="Expr1009"/></OutputList><ComputeScalar><DefinedValues><DefinedValue><ColumnReference Column="Expr1008"/><ScalarOperator ScalarString="CONVERT_IMPLICIT(varchar(15),[DBName].[dbo].[sourceTable].[record_identifier],0)"><Convert DataType="varchar" Length="15" Style="0" Implicit="1"><ScalarOperator><Identifier><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="record_identifier"/></Identifier></ScalarOperator></Convert></ScalarOperator></DefinedValue><DefinedValue><ColumnReference Column="Expr1009"/><ScalarOperator ScalarString="CONVERT_IMPLICIT(binary(8),[DBName].[dbo].[sourceTable].[ModifiedTS],0)"><Convert DataType="binary" Length="8" Style="0" Implicit="1"><ScalarOperator><Identifier><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="ModifiedTS"/></Identifier></ScalarOperator></Convert></ScalarOperator></DefinedValue></DefinedValues><RelOp NodeId="2" PhysicalOp="Top" LogicalOp="Top" EstimateRows="170" EstimateIO="0" EstimateCPU="1.7e-005" AvgRowSize="58" EstimatedTotalSubtreeCost="0.00496748" Parallel="0" EstimateRebinds="0" EstimateRewinds="0"><OutputList><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="record_identifier"/><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="last_update"/><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="LastValueUpdate"/><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="ModifiedTS"/><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="OtherValue_lastUpdate"/></OutputList><RunTimeInformation><RunTimeCountersPerThread Thread="0" ActualRows="69" ActualEndOfScans="1" ActualExecutions="1"/></RunTimeInformation><Top RowCount="1" IsPercent="0" WithTies="0"><TopExpression><ScalarOperator ScalarString="(0)"><Const ConstValue="(0)"/></ScalarOperator></TopExpression><RelOp NodeId="3" PhysicalOp="Clustered Index Seek" LogicalOp="Clustered Index Seek" EstimateRows="170" EstimateIO="0.00460648" EstimateCPU="0.000344" AvgRowSize="58" EstimatedTotalSubtreeCost="0.00495048" TableCardinality="1402" Parallel="0" EstimateRebinds="0" EstimateRewinds="0"><OutputList><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="record_identifier"/><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="last_update"/><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="LastValueUpdate"/><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="ModifiedTS"/><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="OtherValue_lastUpdate"/></OutputList><RunTimeInformation><RunTimeCountersPerThread Thread="0" ActualRows="69" ActualEndOfScans="1" ActualExecutions="1"/></RunTimeInformation><IndexScan Ordered="1" ScanDirection="FORWARD" ForcedIndex="0" ForceSeek="0" ForceScan="0" NoExpandHint="0"><DefinedValues><DefinedValue><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="record_identifier"/></DefinedValue><DefinedValue><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="last_update"/></DefinedValue><DefinedValue><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="LastValueUpdate"/></DefinedValue><DefinedValue><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="ModifiedTS"/></DefinedValue><DefinedValue><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="OtherValue_lastUpdate"/></DefinedValue></DefinedValues><Object Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Index="[idx_sourceTable_modifiedts]" IndexKind="Clustered"/><SeekPredicates><SeekPredicateNew><SeekKeys><StartRange ScanType="GT"><RangeColumns><ColumnReference Database="[DBName]" Schema="[dbo]" Table="[sourceTable]" Column="ModifiedTS"/></RangeColumns><RangeExpressions><ScalarOperator ScalarString="CONVERT_IMPLICIT(timestamp,[@modifiedts],0)"><Identifier><ColumnReference Column="ConstExpr1010"><ScalarOperator><Convert DataType="timestamp" Style="0" Implicit="1"><ScalarOperator><Identifier><ColumnReference Column="@modifiedts"/></Identifier></ScalarOperator></Convert></ScalarOperator></ColumnReference></Identifier></ScalarOperator></RangeExpressions></StartRange></SeekKeys></SeekPredicateNew></SeekPredicates></IndexScan></RelOp></Top></RelOp></ComputeScalar></RelOp></Update></RelOp><ParameterList><ColumnReference Column="@modifiedts" ParameterCompiledValue="0x00000000008EB813" ParameterRuntimeValue="0x0000000000914056"/></ParameterList></QueryPlan></StmtSimple></Statements></Batch></BatchSequence></ShowPlanXML>

【问题讨论】:

  • 参数嗅探可能吗?
  • 感谢您的回复。我要说的可能是错误的:但这里似乎不是参数嗅探,因为执行计划是相同的,因为在生产和时间点执行期间都使用了聚集索引查找。也不应该影响实际行数吗?话虽如此,我会尝试通过优化重新编译以获得实际值,以确保不会出现这种情况。
  • 也许你在backupproduction上有不同的set options
  • 是否启用了自动创建统计信息和自动更新统计信息?如果表负载过重而这就是您没有启用的原因,请考虑启用AUTO_UPDATE_STATISTICS_ASYNC,但请确保您至少处于SP2 CU4 或SP3,因为与此选项相关的内存泄漏已在CU4 for SP2 中修复。
  • DBCC SHOW_STATISTICS 显示关于表上统计数据的年龄是什么?另一种可能性是它重用了旧的查询计划。在查询中添加OPTION(RECOMPILE) 会导致问题消失吗?或者,在 varbinary 字段上的显式非聚集索引将强制 SQL Server 在写入表时更新统计信息,但这对于服务器来说可能很多索引,具体取决于您的数据。然而,索引将是一个更好的真空解决方案,因为您正在指导服务器维护统计数据,而不是放弃可能的好计划。

标签: sql-server sql-server-2008-r2 sql-execution-plan sqlperformance


【解决方案1】:

问题解决了。错误的 Actual Row Count 是由于统计信息错误,而阻塞是由于针对表运行的大量非常小的排队锁定查询。它们都太小了,即使在 1 秒阈值时也无法生成阻塞报告,但足以导致 10+ 秒范围内的阻塞。 我选择了 READUNCOMMITTED 并更改了应用程序代码以使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    • 2021-12-09
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    相关资源
    最近更新 更多