SQL 2019 UDF (função definida pelo usuário) inlining – SQL TECH BLOG

SQL 2019 UDF (função definida pelo usuário) inlining – SQL TECH BLOG

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br


O SQL Server 2019 traz muitos ótimos novos recursos. Muitos são introduzidos pelos recursos IQP (Intelligent Query Processing) e melhoram bastante o desempenho da consulta.

Há algum tempo, publiquei sobre a proteção de Halloween e como o uso de SCHEMABINDING em suas UDFs escalares pode eliminar a necessidade de operadores feios de SPOOL. Você pode ler mais sobre isso aqui: https://sqltechblog.com/2016/10/31/why-halloween-slowed-your-queries/

A Microsoft tem um ótimo post sobre esse novo recurso aqui:

https://docs.microsoft.com/en-us/sql/relational-databases/user-defined-functions/scalar-udf-inlining?view=sql-server-ver15

Quanto à proteção do Dia das Bruxas, vamos ver rapidamente como isso se comporta no SQL Server 2019.

Como uma atualização rápida, o SQL Server 2017 e versões mais antigas se comportam assim sem usar SCHEMABINDING.

 image

Observe que a primeira consulta, que usa a UDF escalar, tem um custo mais alto devido à SPOOL.

Se executarmos isso no SQL Server 2019 usando o modo de compatibilidade 150, o que acontece?

 image

Woohoo! O SPOOL se foi sem ter que alterar o código e qualquer coisa que melhore o desempenho sem alterações no código é incrível!

Pegadinhas

Como você deve ter adivinhado. O inline UDF é bastante novo e melhorará com o tempo à medida que o recurso amadurece. Você pode observar que há hotfixes lançados para corrigir alguns bugs relacionados a esse novo recurso. (https://support.microsoft.com/en-us/help/4538581/fix-scalar-udf-inlining-issues-in-sql-server-2019)

Atualmente, o SQL Server 2019 CU4 é o mais recente e parece que ainda há trabalho a ser feito.

O seguinte bloco de código parece reproduzir um bug na última atualização atual:

CREATE DATABASE ReproBug;
VAI
USE ReproBug
VAI
CREATE TABLE Contato (id int identity (1,1), fname varchar (50), lname varchar (50));
VAI

USE ReproBug
VAI
CRIAR OU ALTERAR PROCEDIMENTO [dbo].[proc_InsertContact]
(
@lastName VARCHAR (100),
@firstName VARCHAR (100)
)
COMO
INÍCIO
BEGIN TRAN

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br

BEGIN TRY
INSERIR EM Contato (fname, lname) valores (@lastName, @firstName);

COMMIT
retornar 0;
TESTE FINAL
COMEÇAR A CAPTURA
ROLLBACK TRAN
RETURN dbo.fx_GetErrorNumber (Error_number ());
FIM DA CAPTURA
FIM
VAI

CRIAR OU ALTERAR FUNÇÃO [dbo].[fx_GetErrorNumber] (@errorCode INT = NULL)
VOLTA INT AS
INÍCIO

DECLARAR @retValue INT
SET @retValue = 500

IF (@errorCode = 2627)
SET @retValue = 501

RETURN @retValue
FIM
VAI

exec dbo.[proc_InsertContact] @ lastName = ‘Vader’, @ firstName = ‘Darth’;

Msg 596, Nível 21, Estado 1, Linha 43
Não é possível continuar a execução porque a sessão está no estado de interrupção.
Msg 0, Nível 20, Estado 0, Linha 43
Um erro severo ocorreu no comando atual. Os resultados, se existirem, deveriam ser descartados.

Existe uma solução alternativa?

Sim; você pode definir o modo de compatibilidade como 140 ou alterar o UDF para desativar o inlining. Mude a própria UDF com “COM INLINE = DESLIGADO“Ou atualize o banco de dados para desativar o inlining”ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = OFF;

Este é um problema que estou assistindo e acompanharei esta postagem quando esse problema for resolvido.



Leia Também  As orientações da Microsoft sobre como definir o MAXDOP foram alteradas