sql - 在 Microsoft SQL Server 中,是否可以以某种方式加速 Lag()?
问题描述
似乎(几乎)在聚集索引上扫描表,从“以前的记录”中总结一个字段,就像在整个表中总结该字段一样容易。但是没有:(有什么我能做的吗?
create table #Tmp(n int not null primary key)
insert into #Tmp values(0)
declare @k int = 1
while @k < 1024 * 1024 * 32
begin
insert into #Tmp
select n + @k
from #Tmp
select @k = @k + @k
end
declare @dummy bigint
declare @d1 datetime = GetDate()
select
@dummy = Sum(Convert(bigint, n))
from
#Tmp
declare @d2 datetime = GetDate()
select
@dummy = Sum(convert(bigint, n0))
from
(
select
n0 = Lag(n) over (order by n)
from
#Tmp
) as Q
declare @d3 datetime = GetDate()
select Convert(time(3), @d2 - @d1), Convert(time(3), @d3 - @d2)
-- 00:00:01.460, 00:00:46.273
drop table #Tmp
解决方案
使用 2019 之前的 SQL Server,您可以通过创建具有列存储索引的虚拟表来利用批处理模式的一些好处。
在 SQL Server 2016 上运行窗口函数查询需要 25 秒:
但是,在创建下表之后
create table dbo.bmode (Id int not null)
create nonclustered columnstore index CC_BatchModeHack on dbo.bmode (Id)
我可以使用外连接将它包含在查询中。它实际上根本不参与查询,但会诱使优化器为窗口函数选择批处理模式
select @dummy = Sum(Convert(bigint, n0))
from (
select n0 = Lag(n) over (order by n)
from #Tmp
left join bmode on 1=0
)q
结果是执行时间下降到几乎 2 秒
推荐阅读
- botframework - 从 Azure Bot 获取所有对话
- c++ - 如果已经运行,则 C++ 程序将进程置于前台,否则创建一个新进程
- ios - How to keep navigation bar title large after pushing view controller from TableView
- django - 成功重定向到配置文件表单会在 /profile/join() 处提供 TypeError - 参数必须是 str 或 bytes,而不是“NoneType”
- java - 有没有办法在一个地方更改“所有”Java 相关的“文件和代码”模板?
- c++ - 带有模板化参数的 std::function
- computer-vision - Mask RCNN 中使用什么样的图像进行训练(只有 8 位或 16 位图像或任何深度)?
- android - Android 视图永远不会变得不可见
- php - 如何在 PHP 中将电子邮件标题数据合并到电子邮件 html 消息正文中
- c# - SQL; 如果列已存在,如何跳过“ALTER TABLE”