Gai*_*ius 13 performance sql-server-2005
我有一个最近变得不可预测的 SQL Server 2005,我正在摸索为什么。在几秒钟内执行的查询正在更改计划并花费几分钟(在全表扫描或索引假脱机中花费时间)。现在第一个也是最明显的事情是,统计数据已经过时导致优化器感到困惑,但我相信事实并非如此 - 首先是因为基础数据没有显着变化(例如,在一年的数据之上添加一天的数据已经在表中),其次是因为自动创建统计和自动更新统计都是真的。然而,优化器越来越困惑;在 Tuning Advisor 中运行 SQL 给了我很多CREATE STATISTICS似乎可以修复它的多列语句(直到 SQL 的下一个错误行为)。
我可以用来解决根本原因的任何策略想法吗?为什么“正常”统计数据还不够?
从MSDN:
"插入操作发生在升序或降序键列上升序或降序键列的 统计信息,例如 IDENTITY 或实时时间戳列,可能需要比查询优化器执行的更频繁的统计信息更新。插入操作将新值附加到升序或降序列。添加的行数可能太小而无法触发统计信息更新。如果统计信息不是最新的并且查询从最近添加的行中选择,则当前统计信息将没有这些新值的基数估计值。这可以导致基数估计不准确和查询性能降低。
例如,如果未更新统计信息以包括最近销售订单日期的基数估计,则从最近的销售订单日期中进行选择的查询将具有不准确的基数估计。
维护操作 之后 执行更改数据分布的维护过程(例如截断表或执行大百分比行的批量插入)后,请考虑更新统计信息。这可以避免在查询等待自动统计更新时查询处理的未来延迟。”
您可能会不时在您的系统上使用“EXEC sp_updatestats”(安排在某个时间)或在所有对象上使用函数 STATS_DATE 并查看它们的统计信息上次实际更新的时间,如果此后有太多时间,请使用 UPDATE该特定对象的统计信息。根据我的经验,即使启用了自动统计,我们仍然不得不不时更新统计,因为插入操作没有触发自动更新。
添加我的个人代码(用于为统计更新构建动态语句的每周工作中使用):
select distinct
'update statistics [' + stats.SchemaName + '].[' + stats.TableName + ']'
+ case when stats.RowCnt > 50000 then ' with sample 30 percent;'
else
';' end
as UpdateStatement
from (
select
ss.name SchemaName,
so.name TableName,
so.id ObjectId,
st.name AS StatsName,
STATS_DATE(st.object_id, st.stats_id) AS LastStatisticsUpdateDate
, si.RowModCtr
, (select case si2.RowCnt when 0 then 1 else si2.RowCnt end from sysindexes si2 where si2.id = si.id and si2.indid in (0,1)) RowCnt
from sys.stats st
join sysindexes si on st.object_id = si.id and st.stats_id = si.indid
join sysobjects so on so.id = si.id and so.xtype = 'U' --user table
join sys.schemas ss on ss.schema_id = so.uid
) stats
where cast(stats.RowModCtr as float)/cast(stats.RowCnt as FLOAT)*100 >= 10 --more than 10% of the rows have changed
or ( --update statistics that were not updated for more than 3 months (and rows no > 0)
datediff(month, stats.LastStatisticsUpdateDate, getdate()) >= 3
and stats.RowCnt > 0
)
Run Code Online (Sandbox Code Playgroud)
在这里,我得到了所有超过 3 个月没有更新统计数据的对象,或者自上次统计数据更新以来,它更改了超过 10% 的行。
如果您的最高等待时间是 SOS_SCHEDULER_YIELD,那么您似乎对 CPU 有一些压力。但这可能是其他原因造成的,例如您的设计不再足以满足您的查询要求。我知道你说过你只添加了一天的数据,但你可能已经达到了一个临界点。
您的查询是如何发出的?是动态SQL吗?你在使用存储过程吗?你在使用 sp_executesql 吗?您是否可能有参数嗅探的情况?你的数据库设计是什么样的?PK 和 FK 的关系是什么?
你有一个好的计划的例子吗?如果您能够确定一个好的计划,您可以使用计划指南来强制查询以特定方式执行。
你能举一个好的计划变坏的例子吗?
最后,从 Adam Machanic获取 sp_whoIsActive ( http://whoisactive.com/ )的副本,并使用它来确定有关正在运行的查询的更多信息。如果您希望能够捕获 sp_whoIsActive 的输出,请访问http://www.littlekendra.com/2011/02/01/whoisactive/
| 归档时间: |
|
| 查看次数: |
11114 次 |
| 最近记录: |