我是 CROSS APPLY 的新手,并试图了解它的工作原理。具体来说,在进行一些测试时,我发现在 CROSS APPLY 语句中包含 GROUP BY 子句可以显着提高聚合的性能,但这似乎有点违反直觉。我想让我感到困惑的是操作的精确顺序。
这是我的测试:
declare @cust table (CUSTID int, NAME varchar(30), MaxOrder decimal, TotalAmountSpent decimal, OrderCount int)
declare @order table (OID int, CUSTID int, AMOUNT decimal)
insert into @cust values (01, 'Fred', 0, 0, 0)
insert into @cust values (02, 'Mary', 0, 0, 0)
insert into @cust values (03, 'Karl', 0, 0, 0)
insert into @order values (20, 01, 6.00)
insert into @order values (21, 03, 10.00)
insert into @order values (22, 03, 20.00)
update @cust
set MaxOrder = app.MaxOrder, TotalAmountSpent = app.TotalAmountSpent, OrderCount = app.OrderCount
from @cust c
cross apply (
select MAX(AMOUNT) MaxOrder, SUM(AMOUNT) TotalAmountSpent, COUNT(OID) OrderCount
from @order o
where c.CUSTID = o.CUSTID
group by o.CUSTID
) app
select * from @cust
这会产生正确的结果:
CUSTID NAME MaxOrder TotalAmountSpent OrderCount
1 Fred 6 6 1
2 Mary 0 0 0
3 Karl 20 30 2
注释掉 GROUP BY 会导致 Mary 的值被写为 NULL:
CUSTID NAME MaxOrder TotalAmountSpent OrderCount
1 Fred 6 6 1
2 Mary NULL NULL 0
3 Karl 20 30 2
因此,虽然两个结果集都可以被认为是“正确的”,但第一种方法只影响实际相关的行。在更大的数据集上,这似乎可以大大提高性能。
这是我感到困惑的地方: 一般来说,我相信在任何 SQL 语句中,WHERE 子句都会在 GROUP BY 子句之前处理,不是吗?在这种情况下,SQL Server 查询优化器是否知道在左右表之间应用 WHERE 子句之前先执行 GROUP BY?令我惊讶的是,以这种方式编写它会导致正确的结果和更好的性能。非常感谢对引擎盖下到底发生了什么的解释。
谢谢!