什么原因会导致SQL服务器性能不佳?

9
每当我发现从我的数据库中检索数据的性能很慢时,我会尝试确定我的SQL查询的哪个部分有问题,并尝试优化它并向表中添加一些索引。但这并不总是解决问题。
我的问题是:
是否有其他技巧可以使SQL服务器性能更好?
还有什么其他原因会导致SQL服务器性能变差?

运行分析器,让它告诉你查询在哪里变慢。 - Robert Harvey
我可以知道为什么它被标记为关闭吗? - pang
@pang:可能应该发布在Server Fault上。 - Sasha Chedygov
3
我不明白这个问题为什么要放在服务器故障类别下,除非我们把所有与数据库管理员有关的问题都转到那里。 - Rex M
说实话,“什么不可能导致 SQL Server 性能不佳?”……基本上任何事情都有可能。 - AdaTheDev
显示剩余2条评论
5个回答

22
  • 查询设计不合理
  • 自动增长文件
  • 维护的索引过多
  • 表上缺少索引
  • 未正确选择聚集索引
  • 由于不良维护导致索引碎片化
  • 由于没有聚集索引而导致堆碎片化
  • 索引使用了太高的FILLFACTOR,导致页面分裂过多
  • 索引使用了太低的FILLFACTOR,导致空间使用过度和扫描时间增加
  • 没有适当地使用覆盖索引
  • 使用了非选择性索引
  • 统计信息维护不当(过时的统计信息)
  • 数据库规范化不合理
  • 事务日志和数据共享相同的驱动器轴
  • 错误的内存配置
  • 内存不足
  • CPU不足
  • 慢硬盘
  • 故障的硬盘或其他硬件设备
  • 在数据库服务器上运行3D屏幕保护程序,占用CPU资源
  • 与其他进程共享数据库服务器,竞争CPU和内存
  • 查询之间存在锁竞争
  • 扫描整个大型表的查询
  • 前端代码以低效的方式搜索数据(嵌套循环、逐行扫描)
  • 不必要和/或不是FAST_FORWARD的CURSOR
  • 在游标通过大型表时未设置NOCOUNT。
  • 使用过高的事务隔离级别(例如在不必要时使用SERIALIZABLE)
  • 客户端与SQL Server之间的往返次数过多(界面冗余)
  • 不必要的联接服务器查询
  • 针对远程服务器上没有主键或候选键定义的表的联接服务器查询
  • 选择了太多数据
  • 查询重新编译过度

哦,还可能有其他问题。


LOL 或许明天我会再添加一些 :) - Dave Markle
很棒的列表,但哪些是比其他的更重要的?
  • “SQL服务器和客户端之间的往返延迟”
- Dennis C
@Dennis,这得看情况!也加入了你的建议 :) - Dave Markle
这基本上就是总结了!特别是“太多的索引”和“太少的索引”;-) 找到正确的索引,以及正确的索引数量,是一门黑魔法 :-) - marc_s
1
很高兴你把低效的查询设计放在首位!这是我检查的第一件事情,大多数情况下我都不需要再深入了解。 - HLGEM

2
当我和遇到这个问题的新开发人员交谈时,我通常会发现问题出在以下两个方面之一。如果你遵循以下两条规则,这两个问题都可以解决。
首先,不要检索不需要的数据。例如,如果你正在进行分页,则不要返回100行数据,然后计算哪些行属于该页。让存储过程来解决这个问题,并仅检索你需要的10行。
其次,没有什么比不做更快的了。例如,我曾经在一个系统上工作,在每个页面请求中都检索了用户的完整角色和权限 - 这对于某些用户来说是数百行数据。即使只是在第一次请求时将其保存到会话状态中,然后从那里用于后续请求,也可以减轻数据库的负担。

1
建议您获取一本关于所使用数据库性能调优的好书(这非常依赖于具体的数据库)。这是一个极其复杂的主题,无法通过网络上的概括性回答来解决。
例如,Dave Markle 告诉您低效的查询可能会导致问题,并且有许多许多编写低效查询的方法以及更多修复它们的方法。

0

这是一个非常广泛的问题,已经有很多答案了。但我想要补充一个重要因素 - 页面分裂。问题在于,有好的分裂和坏的分裂。以下是一些好的文章,解释如何使用transaction_log扩展事件来识别坏/恶劣的页面分裂:

  1. 在SQL Server 2012扩展事件中跟踪有问题的页面分裂 - Jonathan Kehayias
  2. 使用事务日志跟踪页面分裂 - Paul Randal

你提到:

我试图优化它并添加一些索引

但是,有时候删除未使用的非聚集索引可以帮助提高性能,因为它有助于减少事务日志。阅读日志性能问题的主要原因

等待统计信息,或者请告诉我哪里不舒服可以帮助您了解如何使用等待统计信息进行性能分析。

要了解一些关于性能的新思路,请查看Performance Considerations - sqlmag.com

  1. 将连接中的表分别放在不同的磁盘上(用于并行磁盘I/O - 文件组)。
  2. 避免在具有少量唯一值的列上进行连接。

要了解JOIN,请阅读高级JOIN技术



0

如果你是数据库新手并且可以访问数据库引擎调整顾问,那么你可以通过启发式调整来优化你的数据库。

基本上,你需要在 SQL Profiler 中捕获正在运行的 SQL 查询,然后将它们提供给 DETA。DETA 会有效地运行这些查询(不会更改你的数据),然后找出你的数据库缺少哪些信息(视图、索引、分区、统计等)以更好地执行这些查询。

然后它可以为你应用这些信息,并在未来监控它们。我并不是说要盲目相信 DETA 或者不去理解就去做事情,但我发现这绝对是一个很好的方式来了解你的查询正在做什么,花费多长时间,以及如何适当地为数据库建立索引。

另外,值得注意的是,在项目开始时投资于一个好的数据库管理员会更好,这样你就有了良好的结构和索引。但这并不是你现在所处的位置...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接