【问题标题】:SQL Server high CPU and I/O activity database tuningSQL Server 高 CPU 和 I/O 活动数据库调优
【发布时间】:2010-02-04 12:17:27
【问题描述】:

我们的应用程序最近往往运行得很慢。在调试和跟踪时发现进程显示高 cpu 周期和 SQL Server 显示高 I/O 活动。能否请您指导如何优化它?

该应用程序现在大约一年了,数据库文件大小不是很大或任何东西。数据库设置为自动收缩。它在win2003、SQL Server 2005上运行,应用程序是一个用c#编码的web应用程序,即vs2005

【问题讨论】:

  • 自动收缩相当于碎片地狱。
  • 如果未设置自动收缩,则数据库日志文件大小往往会增加。但在过去的 6-7 个月里一直如此。
  • @zapping:垃圾。日志文件必须是它的大小,否则您需要日志备份。
  • @gbn 这是否意味着设置自动收缩是个坏主意?
  • 如果日志文件在没有备份的情况下自动收缩,我敢打赌它必须是简单模式,或者是伪简单模式,因为不存在完整备份/TLog 链损坏。

标签: sql sql-server database performance


【解决方案1】:

在您的数据库上运行 SQL Profiler 一段时间,以查看“缓慢”是否是由于任何问题查询造成的。然后您可以分析这些查询以运行任何索引或统计信息以提高性能。

正如评论所暗示的,自动收缩会导致数据库非常分散。数据库通常会根据需要增长,并且通常最好不要担心它想要多大。只要您执行定期事务日志备份,那么最好让它增长。您可能需要问自己,性能是否比购买新的更多磁盘更重要。

您还可以针对数据库运行一些维护计划来重建索引和统计信息。这可能会在短期内解决问题。

【讨论】:

  • 实际上,一个作业计划每天运行两次,以将数据库备份到单独的磁盘。这就是为什么它被设置为自动收缩。
  • +1:自动收缩在 99% 的情况下是个坏主意。肯定在生产中。
  • 如果您的备份如此设置和正确,那么就不需要自动收缩。如果它们在 24 小时后继续显着增长,则说明您的备份中存在问题等。
  • 我不会在一段时间内运行分析器,而是直接通过 DMV 提取查询缓存,这将是一个更快的周转速度 - 但仅限 2k5 或 2k8,2k 仍需要分析器.在此之前,我想我还会检查 perfmon 以检查关键指标、页面预期寿命等
【解决方案2】:
  1. 对硬盘(或至少 mdf/ldf)文件进行碎片整理。
  2. 如果可能,请将 ldf 文件放在与 mdf 不同的硬盘上
  3. 使用 SQL 2005 中的分析工具;它会告诉你哪些请求持续时间最长;然后使用“显示执行计划”工具查看执行步骤;也许你会得到关于应该添加哪些索引的提示;例如,应该避免对大表进行全表扫描。

【讨论】:

  • 应用程序托管在专用服务器上,并且有大量磁盘空间。数据库大小小于 2gb。它在大约 6-7 个月前趋于增长。那是设置自动收缩的时候。但是现在数据库的增长要少得多。
  • +1 如果 autoshink 已打开,那么您的 sql server 数据/日志文件将被碎片化。执行碎片整理的好主意
【解决方案3】:

除了查看查询的性能问题外,我还将检查数据库和数据库中的表是否没有太多碎片。

您可以发出DBCC showcontig 语句来检查这一点。如果它表明这些表非常分散,您应该考虑创建一个定期执行的维护计划。在该维护计划中,您应该指定应该重建索引。通过这样做,表将被碎片整理。

【讨论】:

    【解决方案4】:

    我知道这个线程已经有一段时间了,但我想我会添加我的 2 位。我们在我们的 sql server 2005 生产数据库上遇到问题,其中 cpu 经常整天以 80% 到 100% 的速度运行.我们尝试了运行跟踪、评估作业、碎片整理、释放磁盘空间,以及我们能想到的一切,但没有任何帮助。最后,我们在博客网站上找到了一篇文章(恐怕我们不记得是哪一篇了),它推荐使用 Sql Server 的缺失索引功能。

    事实证明,SQL Server 2005 及更高版本都具有此功能; SQL Server 不断评估和记录它认为有助于提高性能的推荐索引。我们运行下面的查询并实现了前 130 个索引(显示最大潜在收益的索引)。在一天中最繁忙的时段,我们的整体 db cpu 性能现在下降到 30% 到 40%,而且所有用户都告诉我们,他们的应用程序响应速度更快。

    一些注意事项。我们不是 DBA,因此您可以自行决定添加索引。此外,向任何一个表添加过多索引可能会损害性能 - 因此请注意要添加的索引并始终注意索引过载。

    SELECT mid.database_id, 
           db.name,
           migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure, 
           'CREATE INDEX [missing_index_' + CONVERT (varchar, mig.index_group_handle) + '_' + CONVERT (varchar, mid.index_handle) + '_' + LEFT (PARSENAME(mid.statement, 1), 32) + ']' + ' ON ' + mid.statement + ' (' + ISNULL (mid.equality_columns,'') + CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END + ISNULL (mid.inequality_columns, '') + ')' + ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement, 
           migs.*, mid.database_id, mid.[object_id]
    FROM sys.dm_db_missing_index_groups mig 
    INNER JOIN sys.dm_db_missing_index_group_stats migs
        ON migs.group_handle = mig.index_group_handle
    INNER JOIN sys.dm_db_missing_index_details mid
        ON mig.index_handle = mid.index_handle
    INNER JOIN sys.databases db
        ON mid.database_id = db.database_id
    WHERE migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) > 10
    ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC
    

    【讨论】:

      【解决方案5】:

      对于经常使用的查询,您可以使用 EXPLAIN 语句对其进行分析。这将告诉您是否正在使用适当的索引以及正在扫描的行数。

      【讨论】:

      • SSMS 中用于显示执行计划和统计信息的选项至少同样出色。
      【解决方案6】:

      Auto-shrink 的一个问题是您无法控制它何时启动,因此它可以在实时使用期间运行并使一切停止。如果您真的希望缩小数据库,请制定维护计划以在数小时内完成此操作。但实际上,我不确定您何时需要设置此选项。如果有足够的磁盘空间,让数据库自然增长。如果没有,那就得到更多。磁盘空间很便宜,但来自缓慢应用程序的延迟可能会变得很昂贵。同时关闭自动关闭。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 2013-01-07
        • 1970-01-01
        相关资源
        最近更新 更多