包装器 TSQL Table 值函数很慢
Wrapper TSQL Table-valued Function is slow
我构建了一个包装函数,该函数当前仅调用另一个 table 值函数,但它作为客户端处理时间增加了执行时间。有更快的方法吗?
没有包装器:
使用包装器:
包装函数:
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 来完成。
非常感谢您的回复。他们很有见地,我会给他们全部投票。我只是 post 一些代码在这里分享。如果您有任何建议,很高兴听到您的想法。
我真正想要的是从一个视图 运行 Python,我不得不完全转向另一个方向,我认为性能下降了。
似乎 Python 运行s 仅来自存储过程...因此必须使用 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
我构建了一个包装函数,该函数当前仅调用另一个 table 值函数,但它作为客户端处理时间增加了执行时间。有更快的方法吗?
没有包装器:
使用包装器:
包装函数:
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 来完成。
非常感谢您的回复。他们很有见地,我会给他们全部投票。我只是 post 一些代码在这里分享。如果您有任何建议,很高兴听到您的想法。
我真正想要的是从一个视图 运行 Python,我不得不完全转向另一个方向,我认为性能下降了。
似乎 Python 运行s 仅来自存储过程...因此必须使用 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