Sql server 2008 SQL Server性能问题:为什么简单SQL语句和UD标量值函数看起来很昂贵
我们的SQL 2008 r2数据库遇到了一些严重的性能问题。当我们在SQL Server Management Studio中运行“活动监视器”和返回活动对象的SP时,会显示以下三个事务非常昂贵: 查询1:Sql server 2008 SQL Server性能问题:为什么简单SQL语句和UD标量值函数看起来很昂贵,sql-server-2008,database-performance,Sql Server 2008,Database Performance,我们的SQL 2008 r2数据库遇到了一些严重的性能问题。当我们在SQL Server Management Studio中运行“活动监视器”和返回活动对象的SP时,会显示以下三个事务非常昂贵: 查询1: SET @DateMonth = '0' + @DateMonth SET @DateMonth = CAST(datepart(mm, @TheDate) AS VARCHAR(2)) CREATE FUNCTION [dbo].[DateToNGDate] (@TheDate dat
SET @DateMonth = '0' + @DateMonth
SET @DateMonth = CAST(datepart(mm, @TheDate) AS VARCHAR(2))
CREATE FUNCTION [dbo].[DateToNGDate] (@TheDate datetime)
RETURNS VARCHAR(10)
AS
BEGIN
DECLARE @DateYear VARCHAR(4)
DECLARE @DateMonth VARCHAR(2)
DECLARE @DateDay VARCHAR(2)
SET @DateYear = CAST(datepart(yyyy, @TheDate) AS VARCHAR(4))
SET @DateMonth = CAST(datepart(mm, @TheDate) AS VARCHAR(2))
IF (LEN (@DateMonth) = 1) SET @DateMonth = '0' + @DateMonth
SET @DateDay = CAST(datepart(dd, @TheDate) AS VARCHAR(2))
IF (LEN (@DateDay) = 1) SET @DateDay = '0' + @DateDay
RETURN @DateYear+@DateMonth+@DateDay
END
查询2:
SET @DateMonth = '0' + @DateMonth
SET @DateMonth = CAST(datepart(mm, @TheDate) AS VARCHAR(2))
CREATE FUNCTION [dbo].[DateToNGDate] (@TheDate datetime)
RETURNS VARCHAR(10)
AS
BEGIN
DECLARE @DateYear VARCHAR(4)
DECLARE @DateMonth VARCHAR(2)
DECLARE @DateDay VARCHAR(2)
SET @DateYear = CAST(datepart(yyyy, @TheDate) AS VARCHAR(4))
SET @DateMonth = CAST(datepart(mm, @TheDate) AS VARCHAR(2))
IF (LEN (@DateMonth) = 1) SET @DateMonth = '0' + @DateMonth
SET @DateDay = CAST(datepart(dd, @TheDate) AS VARCHAR(2))
IF (LEN (@DateDay) = 1) SET @DateDay = '0' + @DateDay
RETURN @DateYear+@DateMonth+@DateDay
END
功能:
SET @DateMonth = '0' + @DateMonth
SET @DateMonth = CAST(datepart(mm, @TheDate) AS VARCHAR(2))
CREATE FUNCTION [dbo].[DateToNGDate] (@TheDate datetime)
RETURNS VARCHAR(10)
AS
BEGIN
DECLARE @DateYear VARCHAR(4)
DECLARE @DateMonth VARCHAR(2)
DECLARE @DateDay VARCHAR(2)
SET @DateYear = CAST(datepart(yyyy, @TheDate) AS VARCHAR(4))
SET @DateMonth = CAST(datepart(mm, @TheDate) AS VARCHAR(2))
IF (LEN (@DateMonth) = 1) SET @DateMonth = '0' + @DateMonth
SET @DateDay = CAST(datepart(dd, @TheDate) AS VARCHAR(2))
IF (LEN (@DateDay) = 1) SET @DateDay = '0' + @DateDay
RETURN @DateYear+@DateMonth+@DateDay
END
最后一个是这样返回的,但我很确定它不是在创建函数(它已经存在),而是在运行它。它也是表现得最像性能杀手的一个(它在我们的代码中都有使用)
我确信这些并不是问题的真正原因,但为什么它们看起来像这样?在SQL Server中,标量值函数是一个已知的性能问题。一个选项是如下定义函数:
CREATE FUNCTION [dbo].[DateToNGDateX] (@TheDate datetime)
RETURNS table as return
(
select
cast(
CAST(datepart(yyyy, @TheDate) AS VARCHAR(4)) -- DateYear
+ right('0' + CAST(datepart(mm, @TheDate) AS VARCHAR(2)),2) -- DateMonth
+ right('0' + CAST(datepart(dd, @TheDate) AS VARCHAR(2)),2) -- DateDay
as varchar(30)) as Value
)
select Value from [dbo].[DateToNGDateX] ('20140110');
并参照如下:
CREATE FUNCTION [dbo].[DateToNGDateX] (@TheDate datetime)
RETURNS table as return
(
select
cast(
CAST(datepart(yyyy, @TheDate) AS VARCHAR(4)) -- DateYear
+ right('0' + CAST(datepart(mm, @TheDate) AS VARCHAR(2)),2) -- DateMonth
+ right('0' + CAST(datepart(dd, @TheDate) AS VARCHAR(2)),2) -- DateDay
as varchar(30)) as Value
)
select Value from [dbo].[DateToNGDateX] ('20140110');
但是,对于所需的特定功能,也要进行测试:
select convert(char(8), cast('20140110' as date), 112);
它将返回格式为yyyymmdd的日期。如果select语句返回大量行,标量UDF将非常慢,因为它们将对返回的每一行执行一次。也许您可以根据此链接重写为内联函数我喜欢Pieter Geerkens的答案,我希望它解决了您的问题。无论在何处使用,标量函数都将返回每个匹配行的结果。所以它类似于游标。表值函数将接受一个集合并返回一个集合 要验证两个进程之间的I\O更改,management studio可能没有帮助,但在您自己的计算机上,您可以放置一个小的跟踪,以查看性能的大小
干杯 这怎么会突然成为我们的大问题?多年来,这从来不是一个问题(6+),但毫无疑问,它正在扼杀我们。此外,这不是我们在内部编写的函数,我们支持一个名为NextGen的EHR产品,这是他们的一个库存函数。@jreed121:我无法解释为什么EHR的员工中会有不知道这个问题的无监督初级程序员;你得跟他们谈谈。至于为什么它突然成为一个问题,我建议发布一个查询计划。无论如何,实现此功能的正确方法是使用我上面描述的两种方法之一,并测试哪种方法在您的环境中工作得最好。