如何:将实际执行方法从 "row" 更改为 "batch" - Azure SQL 服务器

How to: Change actual execution method from "row" to "batch" - Azure SQL Server

我遇到了一些重大问题。将数据插入我的数据库时,我使用 INSTEAD OF INSERT 触发器来执行查询。

在我的 TEST 数据库中,此查询插入单行所需的时间不到 1 秒。但是在生产中,此查询需要更长的时间(1 行 > 30 秒)。

比较两者的执行计划时,似乎存在一些明显的差异:

  1. 测试有:"Actual Execution Method: Batch"
  2. 产品有:"Actual Execution Method: Row"
  3. 测试有:"Actual number of rows: 1"
  4. 产品有:"Actual number of rows 92.000.000"

不到一周前,生产 运行 与测试相似。但现在不是了 - 可悲的是。

你们谁能帮我弄清楚原因吗?

我相信,如果我能得到相同的执行计划,应该没问题。

我找到了一个比较满意的解决方案来解决我的问题。

通过使用 Microsoft SQL Server Management Studio 进入数据库的查询存储,我能够为特定查询强制执行特定计划 - 但前提是查询已经制定了计划。

有时使用查询提示 OPTION(hash Join) 有助于强制查询计划使用批处理模式。以下使用 AdventureWorks2012 示例数据库的查询演示了我的意思。

SELECT s.OrderDate, s.ShipDate, sum(d.OrderQty),avg(d.UnitPrice),avg(d.UnitPriceDiscount)
FROM Demo d 
join Sales.SalesOrderHeader s
on d.SalesOrderID=s.SalesOrderID
WHERE d.OrderQty>500
GROUP BY s.OrderDate,s.ShipDate

以上查询使用行模式。有了查询提示,它就会使用批处理模式。

SELECT s.OrderDate, s.ShipDate, sum(d.OrderQty),avg(d.UnitPrice),avg(d.UnitPriceDiscount)
FROM Demo d 
join Sales.SalesOrderHeader s
on d.SalesOrderID=s.SalesOrderID
WHERE d.OrderQty>500
GROUP BY s.OrderDate,s.ShipDate
OPTION(hash Join)

您不能直接在 SQL 服务器中强制执行行与批处理。这是优化器中的 cost-based 决定。您可以(正如您所注意到的那样)强制执行使用批处理模式生成的计划。但是,没有特定的 "only use batch mode" 模型,因为它并不总是最快的。批处理模式执行就像汽车发动机上的涡轮增压器 - 当您处理较大的行集时它效果最好。它在小基数 OLTP 查询上可能会更慢。

如果您有 1 行与 9200 万行的情况,那么您会遇到更大的问题,即查询中处理的行数差异很大。如果您对参数敏感或内部查询计划的形状可能会导致有时您只有一行而不是 92M,那么很难使查询对所有场景都是最佳的。最终,此类问题的解决方案要么是使用 option(recompile) 如果编译的成本远小于计划错误的差异,要么(正如您所做的那样)在查询存储中找到一个特定的计划你可以强制它在所有情况下都能很好地工作。

希望这有助于解释幕后发生的事情。