LowlyDBA - John M Asked: 2018-09-07 06:05:47 +0800 CST2018-09-07 06:05:47 +0800 CST 2018-09-07 06:05:47 +0800 CST 为什么我的查询在环境 A 中运行得很快,而在环境 B 中却很慢? 772 我有一段 SQL 似乎在环境 A 中运行得非常快,但完全相同的查询在环境 B 中运行得非常慢! 环境应该是相同的,所以我应该怎么做和/或我应该去哪里看看为什么查询不执行相同的? sql-server performance 3 个回答 Voted Best Answer LowlyDBA - John M 2018-09-07T06:05:47+08:002018-09-07T06:05:47+08:00 SQL Server 内部和外部的许多因素都可能导致同一查询在不同环境中执行不同,即使它们的配置几乎完全相同,其中任何一个都可能导致查询计划和性能大相径庭。 服务器 跨环境的硬件是否相同(磁盘、内存、CPU 等)? 如果正在使用虚拟机,嘈杂的邻居会影响虚拟机的整体性能吗? 如果在云中,自动缩放和其他配置是否具有奇偶性? 物理/虚拟/云之间的环境是否混合? 操作系统版本是否匹配? 环境是否在不同的数据中心? 实例 SQL Server 版本是否相同? 即使主要版本相同,CU 或 SP 也可以改变世界。 查询执行期间的活动工作负载是否具有可比性? 所有环境中是否存在相同数量的查询? 工作负载的性质在所有环境中是否相同? 是否所有环境都参与相同的 HA/DR 设置? 很多时候,较低的环境没有可用性组、日志传送或复制设置,而生产/灾难恢复可能正在使用这些技术。 相同的维护作业是否在所有环境中按相同的时间表运行? 跟踪标志在所有环境中是否等效? 是否在所有环境中运行相同的备份作业? 备份的影响应该很小,但通常它们根本不会在较低的环境中运行。 sys配置是否相同? 数据库 架构/索引/统计信息/对象在不同环境中是否都相等? 甚至 SELECT 查询也会导致统计信息更新 跨环境 是否存在完全相同的数据? 数据量 数据分布 数据大小(认为可变长度数据类型中的虚拟数据可能无法反映其他环境中实际值的大小) 数据库级别的配置是否相同? 兼容性级别是否相同? 考虑到所有这些,在许多情况下根本不可能在不同的环境中完美地复制数据库的各个方面,这并不奇怪。虽然测试可以很好地确定查询在每个环境中的执行方式,但如果环境之间存在差异也就不足为奇了。在开发新查询时,通常需要在它转向生产时进行额外的调整。 通常,在一个环境中调整较慢的查询不会导致生成的执行计划出现回归,因此这是调整索引、统计信息或查询本身以进行整体改进的机会。 最后说明:较低的环境规模较小,通常不应期望提供与生产或预生产环境相同的性能。 更多资源: Aaron Bertrand的“相同”服务器的不同计划 Phil S 2018-09-07T07:33:32+08:002018-09-07T07:33:32+08:00 其他答案很好,但我要补充一点,您应该考虑环境 B 中的数据量,以及与其他查询的任何争用。 一些 SQL 查询单独显示没有性能问题(例如,表中有 1000 行,没有其他查询在运行),但在表中有 10,000,000 行(例如参数嗅探问题)和/或其他可能写入、更新的查询时可能会令人恐惧或锁定所涉及的表。 我同意首先检查硬件/环境/配置匹配的其他答案,但如果没有明显的问题出现,请开始查看查询执行计划、运行 SQL Profiler 等。 dland 2018-09-07T06:40:04+08:002018-09-07T06:40:04+08:00 简而言之,您需要隔离 db 本身与另一个相比是否较慢,或者其环境较慢。首先排除最简单的事情。 这在我身上发生过几次。每次结果都是环境:其他人正在敲打并饿死一台服务器上的 IOPS 数据库。 在较慢的服务器上运行 top(1) 并查看 CPU 是否正在经历大量等待状态,或者如果您在虚拟环境中,则 cpu 窃取。 这也将有助于指出导致执行计划执行全表扫描而不是索引扫描的缺失索引(但这很容易通过慢查询日志发现)。这也将在 ps 中显示为处于 D 状态的 procs。 一旦排除了这一点,就该深入研究硬件了:工作是否分布在所有 CPU 上,是否有一个网络端口重新协商为 100Mb。在两台机器上运行 vmstat 和/或 iostat 并比较差异。 如果数据集相同,相同的查询是否会在两者上生成相同的执行计划?表是否包含相同数量的行?索引定义是否相同?这些表是否具有相似程度的碎片?相似数量的活动连接?
SQL Server 内部和外部的许多因素都可能导致同一查询在不同环境中执行不同,即使它们的配置几乎完全相同,其中任何一个都可能导致查询计划和性能大相径庭。
服务器
实例
数据库
考虑到所有这些,在许多情况下根本不可能在不同的环境中完美地复制数据库的各个方面,这并不奇怪。虽然测试可以很好地确定查询在每个环境中的执行方式,但如果环境之间存在差异也就不足为奇了。在开发新查询时,通常需要在它转向生产时进行额外的调整。
通常,在一个环境中调整较慢的查询不会导致生成的执行计划出现回归,因此这是调整索引、统计信息或查询本身以进行整体改进的机会。
最后说明:较低的环境规模较小,通常不应期望提供与生产或预生产环境相同的性能。
更多资源:
其他答案很好,但我要补充一点,您应该考虑环境 B 中的数据量,以及与其他查询的任何争用。
一些 SQL 查询单独显示没有性能问题(例如,表中有 1000 行,没有其他查询在运行),但在表中有 10,000,000 行(例如参数嗅探问题)和/或其他可能写入、更新的查询时可能会令人恐惧或锁定所涉及的表。
我同意首先检查硬件/环境/配置匹配的其他答案,但如果没有明显的问题出现,请开始查看查询执行计划、运行 SQL Profiler 等。
简而言之,您需要隔离 db 本身与另一个相比是否较慢,或者其环境较慢。首先排除最简单的事情。
这在我身上发生过几次。每次结果都是环境:其他人正在敲打并饿死一台服务器上的 IOPS 数据库。
在较慢的服务器上运行 top(1) 并查看 CPU 是否正在经历大量等待状态,或者如果您在虚拟环境中,则 cpu 窃取。
这也将有助于指出导致执行计划执行全表扫描而不是索引扫描的缺失索引(但这很容易通过慢查询日志发现)。这也将在 ps 中显示为处于 D 状态的 procs。
一旦排除了这一点,就该深入研究硬件了:工作是否分布在所有 CPU 上,是否有一个网络端口重新协商为 100Mb。在两台机器上运行 vmstat 和/或 iostat 并比较差异。
如果数据集相同,相同的查询是否会在两者上生成相同的执行计划?表是否包含相同数量的行?索引定义是否相同?这些表是否具有相似程度的碎片?相似数量的活动连接?