select 语句中的函数使我的查询运行非常缓慢

Posted

技术标签:

【中文标题】select 语句中的函数使我的查询运行非常缓慢【英文标题】:Function in select statement makes my query run very slowly 【发布时间】:2016-09-11 18:57:26 【问题描述】:

我在存储过程中有这个查询:

SELECT      
    *,
     ISNULL(dbo.ReturnShortageByItemCodeLinePackage(LineId, TestPackageId, MaterialDescriptionId), 0) AS Shortage 
FROM
    dbo.ViewMTO

我在查询中使用一个函数来计算一个整数值,如您在此处看到的:

ALTER FUNCTION [dbo].[ReturnShortageByItemCodeLinePackage]
     (@lineId int,@testpackId int, @MaterialDescriptionId int)
RETURNS float
AS 
BEGIN
    DECLARE @shortageQuantity float
    DECLARE @MIVQuantity float
    DECLARE @totalQuantity float
    DECLARE @spoolQuantity float
    DECLARE @ExistInSiteQuantity float
    DECLARE @BeforeDoneQuantity float

    SELECT  
        @totalQuantity = Quantity,
        @spoolQuantity = QuantitySpool,
        @ExistInSiteQuantity = QuantityExistInSite,
        @BeforeDoneQuantity = QuantityBeforeDone
    FROM 
        [SPMS2].[dbo].Materials 
    WHERE
        LineId = @lineId 
        AND TestPackageId = @testpackId  
        AND MaterialDescriptionId = @MaterialDescriptionId

    SELECT
        @MIVQuantity = SUM(QuantityDeliver) 
    FROM
        MaterialIssueVoucherDetails miv
    JOIN
        MaterialRequestContractorDetails mrc ON miv.MaterialRequestContractorDetailId = mrc.Id
    WHERE
        TestPackageId = @testpackId 
        AND LineId = @lineId 
        AND miv.MaterialDescriptionId = @MaterialDescriptionId

    IF @MIVQuantity IS NULL
    BEGIN
        SET @MIVQuantity = 0    
    END

    SET @shortageQuantity = @totalQuantity - (@BeforeDoneQuantity + @ExistInSiteQuantity + @spoolQuantity + @MIVQuantity)

    RETURN round(@shortageQuantity, 3)
END

我的查询在 3 分钟内执行,这对我的用户来说是灾难性的!有没有更好的解决方案?

【问题讨论】:

ViewMTO 是视图吗? 【参考方案1】:

我可以推荐三件事:

A.下面一行..

SELECT @totalQuantity= ... 
FROM [SPMS2].[dbo].Materials

这是通过链接服务器连接访问不同的数据库吗?这个连接有多快?

B.您的 SP 包含 两个 SELECT 语句。其中哪一个是瓶颈? 您可以添加一些 PRINT 语句来显示每个语句的启动时间:

PRINT convert(nvarchar, GetDate(), 108) + ' This is the time !'

C.尝试在下面我的网页上运行 SQL 显示,它将突出显示缺失的索引。

Find missing indexes

希望这会有所帮助。

【讨论】:

好的...这回答了我的 3 条建议中的 1 条...另外 2 条...?【参考方案2】:

将您的 Scaler 函数转换为表值函数,然后将该函数放在 FROM 子句中以进行 LEFT JOIN。请检查执行计划以发现任何警告。

Testing performance of Scalar vs Table-valued functions in sql server

【讨论】:

以上是关于select 语句中的函数使我的查询运行非常缓慢的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 FROM 子句中再添加一个 INNER JOIN 会使我的 SQL 查询如此缓慢?

优化 SELECT 查询性能

SQL 语句运行缓慢 - 有啥想法吗?

缓慢的 WordPress 默认查询

为啥 Firebase 功能部署非常缓慢?

非常简单的 MySQL 索引查询运行非常缓慢