我有一个 8GB 的表,有 20M 条记录。有一个名为 mth 的 int 字段。第 m 个字段以 YYYYMM 的形式存储日期信息,我想将第 m 个字段转换为连续的整数。所以我用一个公式从字段mth中获取年和月并计算月份顺序,具体我使用以下代码:
create function mth_to_num(@month int)
returns int
as
begin
return(round(@month/100,0)*12+@month-100*round(@month/100,0))
end
然后我使用下面的代码来更新巨大表中的值
update full_orig_month_Q1_1999
set mth_order = dbo.mth_to_num(period)
Go
但是,代码执行时间很长,大约需要 2-3 分钟。我的系统是带有 SQL Server 2016 的 Windows 10 64 位。有什么办法可以加快它的速度吗?
另一个问题是,执行上述查询后,我发现 SQL Server 在数据库中占用了 8GB 之多。需要那么多内存吗?我怎样才能释放它们?
提前感谢您的帮助!
杰森
尽可能不要在查询中使用标量用户定义函数 (UDF)。它们强制整个计划是串行的,它们会导致使用大量额外的 CPU 资源,它们对优化器来说是一个黑匣子,会导致计划其他部分出现基数估计问题,它们会导致不必要的大量内存授予。
尝试在没有 UDF 的情况下运行 UPDATE 查询。只需将您拥有的代码直接放入 UPDATE 查询即可。是这样的:
这会改善运行时和内存使用吗?
您可以尝试使用 Paul Randall 的脚本来捕获脚本执行期间发生的等待统计信息。
根据返回的结果,您可以搜索顶级等待类型并解释性能问题。
示例结果可能如下所示:
搜索 ASYNC_NETWORK_IO 会显示例如:
回应您的评论:
Paul Randall和Brent Ozar的站点是性能调整和优化的良好起点。我仍然发现 SQL Server 2008 R2 联机丛书(仍然可以下载)包含大量关于数据库内部结构的信息,尽管其中一些已经过时。
Aaron Bertrand有一些关于性能调优的有用信息,很多其他人也同样如此。