【问题标题】:Query performance on two databases on one server一台服务器上两个数据库的查询性能
【发布时间】:2016-03-07 11:14:59
【问题描述】:

我看过这个:The Same SQL Query takes longer to run in one DB than another DB under the same server,但我仍然对此感到困惑。我已经在两个数据库上对此进行了测试,具有完全相同的查询计划,但在测试数据库上,此查询运行时间不到 20 毫秒,而在开发数据库上,这需要超过 1 分钟。

需要注意的是,在当前时间点,测试数据库与开发数据库完全相同(请注意,自提出此问题后,架构发生了轻微变化 - 请参阅编辑以获取更多信息)。我正在运行的查询是这样的:

SELECT 
    pn.PARTNO,
    LogisticsComment,
    Length,
    Width,
    Height,
    Weight 
FROM [partDB] pn
INNER JOIN [storeLines] sl
ON pn.PARTNO = sl.PARTNO
INNER JOIN [storeRequests] sr
ON sl.ITEMID = sr.LINEITEMS
WHERE sr.SERIAL = 'S14566'

这是查询执行计划:

我不知道是什么原因造成的。另外需要注意的是,该链接问题有 200 万条记录 - 此查询目前应返回 26 条记录。

编辑:抱歉耽搁了,生活有投掷曲线球的习惯。

根据要求,请查找实时系统和测试系统的 XML。

发展: PasteBin link

测试: PasteBin link

以及实时和测试系统的实际执行计划:

发展:

测试:

编辑 2: 我进行了架构比较,发现此查询中的两列“TMTPARTNO”和“LogisticsComment”具有不同的数据类型 - 在测试系统中,它们分别是 varchar(50) 和 nvarchar(1500),在 live 系统中,它们是 char(18) 和 nchar(1500)。在不更改实时系统中的数据类型的情况下,我想知道性能影响是否在于“LogisticsComment”字段使用了这么多字节?

【问题讨论】:

  • 在问题中包含 实际 执行计划的 XML,用于 both 快速和慢速查询。在 SSMS 中勾选菜单查询 - 包括实际执行计划。在带有查询结果和计划的窗口中,右键单击并显示执行计划 XML。
  • 所以,只是指出 - 你提到数据库是相同的,但最后你说它们不是。我会更深入地挖掘其他细微的差异。也许运行 generate scripts 命令并使用 diff 工具比较输出。
  • 关于downvote,本站对于SQL性能是否“编程”存在一些冲突。我支持它,因为这种质量的帖子很少见!
  • 我设法打开了第一个计划(但不是第二个 - 出现 xml 错误)。如果您捕获 实际 计划,也可能会提供信息,这意味着按 查询 然后 包括实际执行计划。然后运行您的查询。例如,您会在计划中看到“估计行数”和“实际行数”。
  • 我还建议您将 prod 更改应用回测试,看看它是否会引入问题。

标签: sql-server database join indexing


【解决方案1】:

在问题的开头,您谈论的是测试与开发数据库;稍后您将参考测试与现场。很混乱。

查看两个执行计划时都会出现警告:

Live - Cardinality Estimate Expression="CONVERT_IMPLICIT(nchar(18),[pn].[PartNumber],0)"

Test - Cardinality Estimate Expression="CONVERT_IMPLICIT(nvarchar(50),[pn].[PartNumber],0)"

两个数据库中pn.PartNumbersl.PartNumber字段的类型是什么?

显然它们在两种情况下都不匹配,这不好。在一种情况下,不匹配可能会导致更严重的后果。估计的行数略有不同(3 对 4),实际返回的行数为 26。

计划的另一个不同之处:

实时计划使用STORES-REQ-LINK 上的索引,称为STORES-REQ-LINK_SerialIndex

测试计划使用STORES-REQ-LINK 上的索引,称为STORES-REQ-LINK_Index02122015

这些索引是否相同?

表基数略有不同:110077 与 106488、97535 与 92892,这解释了估计行数的细微差异。

因此,数据库在结构和实际数据方面都不相同。使它们相同并再次比较性能是有意义的。

说了这么多,您的表并不大(约 100K 行),所以这种查询不应该花费几分钟。

这两个数据库在同一台服务器上,所以CPU和内存应该是一样的。它们是否位于同一个硬盘上?

不过,这些计划非常相似,查询处理的实际数据大小很小(77KB 对 39KB),因此这种性能上的巨大差异很可能是由某些阻塞/锁定引起的。慢查询很可能只是在等待一些资源。你在这两个数据库上都有什么样的活动?

【讨论】:

  • 对不一致的命名表示歉意-我已在原始帖子中修复了此问题。至于sl.PartNumber和pn.PartNumber的字段类型,在开发系统中确实不匹配;然而,它们在测试系统中很接近——但并不完全相同。索引是相同的,但是实时/开发计划中的名称是在创建时命名的,但在测试中它只留下了一个日期戳索引(再次,用于测试)。是的,它们在同一个磁盘上——然而,开发系统接收的流量比测试系统多得多。连接数大约是测试的 20 倍。
  • 感谢您的回答弗拉基米尔和您的时间。我将更深入地研究 XML 以了解它,但出于好奇,您在比较两个执行计划时特别注意什么?我希望学习,以便下次我不会在没有一些知识基础的情况下提出问题。谢谢!
  • @DeeKayy90,在这种情况下,计划确实看起来非常相似,这表明慢速系统一定在等待某些东西。或者还有其他一些外部原因。如果性能差异是由计划或数据的实质性差异引起的,您会看到处理的实际数据大小的差异; IO(读取次数);计划形状。您只查看了计划形状,下一步是检查 IO(读取)、行数、处理的字节数。看了所有这些,您可以确认问题出在其他地方。然后查看等待统计信息,服务器的整体性能统计信息。
  • 感谢您更详细地解释这一点@VladimirBaranov,我很感激。我会看看性能瓶颈是来自系统还是它正在等待的进程。
猜你喜欢
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-03
  • 1970-01-01
相关资源
最近更新 更多