包装器 TSQL 表值函数很慢

问题描述

我构建了一个包装函数,它目前只调用一个表值函数,但它只是增加了大量的执行时间作为客户端处理时间。有没有更快的方法来做到这一点?

无包装:

enter image description here

带包装器:

enter image description here

包装函数

CREATE FUNCTION [console].[getCalculosRequisita]
(   

    @disponivel BIGINT,@mediaDiaria float,@DiasstockArtigo INT,@DiasAntes INT,@SaidasPorMes float,@QtdEncomendada2Meses BIGINT,@StockAtual BIGINT,@QtdRequisitada BIGINT,@caixaMinima INT

)
RETURNS @tbl TABLE 
(
    DiasAteRotura INT,AcaoRequisita varchar(10),Aconselhada BIGINT
)
AS
BEGIN

--future configuration check
--future log input

INSERT INTO @tbl SELECT DiasAteRotura,AcaoRequisita,Aconselhada
FROM [cartridge].[getCalculosRequisitaTsql]
(
    @disponivel,@mediaDiaria,@DiasstockArtigo,@DiasAntes,@SaidasPorMes,@QtdEncomendada2Meses,@StockAtual,@QtdRequisitada,@caixaMinima
)


--future log output

RETURN
END

GO

解决方法

将其作为内联 TVF 执行,速度要快得多:

CREATE FUNCTION [console].[getCalculosRequisita]
(   

    @Disponivel BIGINT,@mediaDiaria float,@DiasStockArtigo INT,@DiasAntes INT,@SaidasPorMes float,@QtdEncomendada2Meses BIGINT,@StockAtual BIGINT,@QtdRequisitada BIGINT,@caixaMinima INT
)
RETURNS TABLE -- WITH SCHEMABINDING  -- preferable,but then you can't change the underlying function
(
    DiasAteRotura INT,AcaoRequisita varchar(10),Aconselhada BIGINT
)
AS RETURN
(SELECT DiasAteRotura,AcaoRequisita,Aconselhada
FROM [cartridge].[getCalculosRequisitaTSQL]
(
    @Disponivel,@mediaDiaria,@DiasStockArtigo,@DiasAntes,@SaidasPorMes,@QtdEncomendada2Meses,@StockAtual,@QtdRequisitada,@caixaMinima
) AS t
);
GO

显然,如果你这样做,那么你不能做任何其他的插入。无论如何,日志记录都是不可能的,所以我不确定你打算做什么。

您没有给出底层函数的代码。也许这也可以作为 iTVF 来完成。

,

我非常感谢您的回复。他们很有见地,我会支持他们。我只是在这里发布一些代码以供分享。如果您有任何建议,很高兴听到您的想法。

我真正想要的是从视图中运行 Python,我不得不完全转向另一个方向,我认为性能已经付诸东流。

似乎 Python 只能从存储过程中运行...所以必须使用 OPENROWSET (!?) 才能将其作为 VIEW。不漂亮,下面的例子:

DROP PROC IF EXISTS PythonExample;
GO
CREATE PROC PythonExample
AS
BEGIN

set nocount on
SET FMTONLY OFF

    DROP TABLE [dbo].[MyRows]
    CREATE TABLE [dbo].[MyRows](
        [RowNum] [int] NULL
    ) ON [PRIMARY]
    

    INSERT INTO [MyRows] 
        ([RowNum]) 
    VALUES 
        (1),(2)

    DECLARE @tbl1 TABLE 
    (
       COL1 INT,COL2 INT
    )

    INSERT INTO @tbl1

---ATTENTION Identing is important for Python code...
    EXEC sp_execute_external_script  @language =N'Python',@script=N'
import pandas as pd
df= MyInput
df["newCol"]= df["RowNum"]*2
MyOutput = df;
    ',@input_data_1_name = N'MyInput',@input_data_1 =N'SELECT [RowNum] FROM [MyRows]',--- it seems it cannot handle a temp table
    @output_data_1_name =N'MyOutput'
    --WITH RESULT SETS ((MyColName int,MyColName2 int));

    SELECT * FROM @tbl1
END;
GO

DROP VIEW IF EXISTS ViewExample;
GO
CREATE VIEW ViewExample
AS
    SELECT * FROM OPENROWSET('SQLNCLI','Server=localhost;Trusted_Connection=yes;','exec [dbo].[PythonExample]')
GO

SELECT * FROM ViewExample