SQL Server性能突然下降


13

我有一个SQL Server 2005,它最近已经变得不可预测,并且我为之why恼。在几秒钟内执行的查询正在更改计划并花费数分钟(花费时间进行全表扫描或索引假脱机)。现在最明显的是,统计数据已过时,导致优化程序感到困惑,但我坚信情况并非如此-首先,因为基础数据没有发生重大变化(例如,将一年的数据添加到一年的数据之上)已经存在于表格中),其次是因为“自动创建统计信息”和“自动更新统计信息”均为true。然而,优化变得混乱了。在Tuning Advisor中运行SQL给了我许多CREATE STATISTICS似乎可以解决它的多列语句(直到下一个SQL行为异常)。

有什么我可以用来解决根本原因的策略构想吗?为什么“正常”统计数据还不够?

Answers:


8

如果最等待的时间是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/


这是第三方应用程序,我无法控制其架构或SQL,这非常可怕,有很多参数化查询(例如where col=(cast @var...)),@var可能是'%'。我只是在一两个星期前继承了它,所以需要使其基本运转直到被替换。谢谢你的链接,我会旋转的。
盖乌斯

下一轮最大的等待SOS_SCHEDULER_YIELDCXPACKET而且sp_configure "max degree of parallelism", 1现在似乎已经敲响了两个问题。谢谢!
盖乌斯

+1链接到sp_whoIsActive
Jeff

8

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
    )

在这里,我得到了三个月以来没有更新任何统计信息的所有对象,或者自上次统计信息更新以来,它更改了超过10%的行。


嗯,我的最重要的等待事件是,SOS_SCHEDULER_YIELD但是我现在无法确定这是由于错误的计划造成的,还是这个(具有6年历史,2个处理器,4G RAM的)存储盒现在真的过载了,我已经超过了临界点
盖乌斯

而不是仅运行该查询以生成UPDATE语句并手动运行它们,您可以使用基于该select语句的游标通过对sp_executesql的调用来循环运行它们的结果-这样,您可以自动运行它(例如,作为一部分运行一夜(或其他安静时期)的维护计划)。
David Spillett

@David:这就是我每周的工作:)。我为Gaius设置了不同的格式,以查看我正在使用的输出。最初的脚本太丑陋且太长。感谢您提供格式化帮助!您能否将我发送到格式教程。.因为我真的不知道如何使代码在这里看起来不错。谢谢!
玛丽安

在“编辑答案”屏幕上有一个“格式设置帮助”链接,在主问题页面上初始答案框上方的右侧是一个图标,列出了这些网站支持的降价语法。
David Spillett

3
自动更新统计信息实际上在20%+ 500行而不是10%时触发。
mrdenny

3

我的猜测是您的一个或多个表足够大,以至于它们没有达到将当前统计信息标记为过时所需的20%的更改,因此自动更新统计信息将启动,但有足够的更新(或插入) ),更新统计信息将大有帮助。从SQL 2000升级到SQL 2008之后,我最近在特定环境中发现了同样的事情。

除了以上答案中提到的其他网站,我建议您查看以下在线资源。

1)Red-Gate有许多免费的电子书可供下载,包括Holger Schmeling的“ SQL Server Statistics”,您将在其中找到以下引文:

http://www.red-gate.com/our-company/about/book-store/

“必须更改具有500行以上,至少一列数据的20%的表,以使任何链接的统计信息无效”

2)SQL Sentry有一个免费的Plan Explorer工具,该工具可帮助跟踪SQL计划中的问题,例如,与查询中给定表的实际行数相比,估计行太多或太少。只需从SSMS保存实际的执行计划,然后使用计划资源管理器遍历计划的不同部分。并不是说使用图形执行计划在SSMS中没有信息,但是SQL Sentry的工具确实使查看起来更加容易。

http://www.sqlsentry.com/plan-explorer/sql-server-query-view.asp

3)使用STATS_DATE()自己查询最感兴趣的查询中的表的统计信息更新日期,您可以使用以下讨论中找到的查询找到快速查询以获取最早的统计信息。

http://blog.sqlauthority.com/2010/01/25/sql-server-find-statistics-update-date-update-statistics/

我希望这有帮助!

我想您会特别喜欢Red-Gate的书!

杰夫


谢谢,我将逐步解决这些问题。我主要是一个继承了此系统的Oracle DBA(因此,我完全不反对SQL Server,从2005年以来我看到它是一个非常强大的平台,我只是不了解它,而我也了解Oracle) 。
盖乌斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.