【问题标题】:SQL query faster on slower machineSQL 查询在较慢的机器上更快
【发布时间】:2025-12-19 22:35:09
【问题描述】:

我们有两台运行 MS SQL 2012 的 MS SQL 服务器。一台有 8GB RAM、2 个处理器和足够的存储空间。另一个有 8 个处理器、64GB RAM、多个连接的驱动器,数据、程序、日志和 tempdb 是分开的。

通常,大型服务器的查询速度更快。但是,在一个简单的查询中,小机器需要 10 秒,而另一台机器需要 5 分钟。据我们判断,SQL Server设置一样,数据一样,两台机器上查询一样,估计和实际执行计划一样,但是大机器慢. Tempdb是小机上与SQL.exe同盘的一个文件,大机SSD盘上的tempdb有8个文件。

我们可以按照哪些步骤来确定为什么大型机器上的少数查询比小型机器上的速度慢?

查询是:

SELECT field1, field2 
FROM lookuptable1
WHERE field2 <> '' 
AND field1 not in (SELECT field1 
    FROM lookuptable2
)

我们在大型机器上有 16 个线程用于并行任务,在小型机器上有 4 个线程。该查询不返回任何值(预期),但使用更大的机器会慢得多。已重建统计信息并刷新查询计划。

【问题讨论】:

  • 如果你真的确定数据是一样的,下一步应该是确保结构也是一样的(约束、触发器、索引...)
  • 嗯好吧,你说实际的执行计划是一样的?仔细检查,数据相同;手动运行查询(您是否还使用 Profiler 检查它们?)。也可能是您的“大型服务器”比小型服务器更容易受到攻击,这意味着执行计划可能是最佳的,但是服务器的使用量如此之大,您必须稍等片刻......
  • 有没有对比过set statistics io on在两台机器上运行的结果?使用set showplan_xml on 然后在差异工具中查看可能会很有见地。
  • 我的猜测是,基于我在之前评论中链接的两篇文章中的某些内容,实际计划会有所不同(并且不要费心看估计计划)。对于实际计划,您是否验证所有估计/实际行数都相同?图表不是唯一需要检查的东西。您还可以使用扩展事件来跟踪执行查询的会话所产生的等待,这样您就可以比较查询在更强大的机器上所做的事情,而在小型机器上却没有发生。您应该在计划、等待或两者中找到证据。

标签: sql-server adhoc-queries


【解决方案1】:

测试是否存在(与 IN 相比)可能会有所不同。

SELECT field1, field2 
FROM lookuptable1 outerTableAlias
WHERE field2 <> '' 
AND not exists (SELECT * 
    FROM lookuptable2 innerTable where innerTable.field1 = outerTableAlias.field1 )

)

尝试不带“field2 ''”的查询。对于 table_scan,这将是一个高度可疑的地方。

【讨论】:

  • 我对 IN 与 EXISTS 查询的经验是,它需要进行测试和尝试。但是感谢您的反对......
  • 这不是我的反对意见,但您可能想先阅读这篇文章,然后再对使用 IN 做出如此广泛的声明。 sqlinthewild.co.za/index.php/2009/08/17/exists-vs-in 我倾向于使用 EXISTS,就像你在这里的例子一样。减轻 '' 很简单。只需将其更改为 > ''
  • 感谢文章参考。我改变了我的帖子,说“试试看”而不是教条式的陈述。就我个人而言,我在我的生活中看到了大约 3 个查询,其中存在的地方有很大的不同。我还有一个喜欢嵌套 IN 子句的开发人员。 3 个月后,这个人无法告诉你为什么(这个人)这样写。所以我厌倦了。