Scalar UDF inlining (Podkreślenie funkcji UDF skalarnych)
Dotyczy: SQL Server 2019 (15.x)
Azure SQL Database
Azure SQL Managed Instance
W tym artykule przedstawiono skalarną funkcję definiowaną przez użytkownika (UDF) jako część pakietu funkcji w ramach Inteligentnego przetwarzania zapytań w bazach danych SQL. Ta funkcja poprawia wydajność zapytań, które wywołują skalarne funkcje zdefiniowane przez użytkownika (UDF) w programie SQL Server 2019 (15.x) i nowszych wersjach.
Funkcje skalarne zdefiniowane przez użytkownika w języku T-SQL
User-Defined Functions (UDF), które są implementowane w Transact-SQL i zwracają pojedynczą wartość danych, są określane jako funkcje języka T-SQL Scalar User-Defined. Funkcje zdefiniowane przez użytkownika w T-SQL to elegancki sposób na ponowne użycie kodu i modułowość w zapytaniach Transact-SQL. Niektóre obliczenia (takie jak złożone reguły biznesowe) są łatwiejsze do wyrażenia w postaci imperatywnej funkcji zdefiniowanej przez użytkownika. Funkcje zdefiniowane przez użytkownika pomagają w budowaniu złożonej logiki, nie wymagając przy tym biegłości w pisaniu złożonych zapytań SQL. Więcej informacji na temat funkcji zdefiniowanych przez użytkownika znajdziesz w Tworzenie funkcji zdefiniowanych przez użytkownika (silnik bazy danych).
Wydajność skalarnych funkcji zdefiniowanych przez użytkownika
Skalarne funkcje zdefiniowane przez użytkownika zwykle kończą się niską wydajnością z następujących powodów:
Wywołanie iteracyjne. Funkcje zdefiniowane przez użytkownika są wywoływane w sposób iteracyjny, raz na kwalifikowaną krotkę. Wiąże się to z dodatkowym kosztem wielokrotnego przełączania kontekstu z powodu wywołania funkcji. Zwłaszcza funkcje zdefiniowane przez użytkownika, które wykonują zapytania Transact-SQL w swojej definicji, są poważnie dotknięte.
Brak analizy kosztów. Podczas optymalizacji koszty są przypisywane tylko operatorom relacyjnym, natomiast operatory skalarne nie są uwzględniane. Przed wprowadzeniem skalarnych funkcji zdefiniowanych przez użytkownika inne operatory skalarne były zazwyczaj tanie i nie wymagały określania kosztów. Niewielki koszt procesora dla operacji skalarnej był wystarczający. Istnieją scenariusze, w których rzeczywisty koszt jest znaczący, a jednak nadal pozostaje niedostatecznie reprezentowany.
Interpretowane wykonanie. Funkcje zdefiniowane przez użytkownika są przetwarzane jako zestaw instrukcji, wykonywane krok po kroku. Każda instrukcja jest kompilowana, a skompilowany plan jest buforowany. Mimo że ta strategia buforowania oszczędza trochę czasu, ponieważ pozwala uniknąć ponownej kompilacji, każda instrukcja jest wykonywana w izolacji. Nie są przeprowadzane żadne międzystanowe optymalizacje.
Wykonywanie szeregowe. Program SQL Server nie zezwala na równoległość wewnątrz zapytań w zapytaniach, które wywołują funkcje zdefiniowane przez użytkownika.
Automatyczne wstawianie skalarnych UDF-ów
Celem funkcji śledzenia skalarnej UDF jest zwiększenie wydajności zapytań, które wywołują skalarne funkcje UDF w języku T-SQL, gdzie ich wykonanie stanowi główne wąskie gardło.
Dzięki tej nowej funkcji skalarne funkcje zdefiniowane przez użytkownika (UDF) są automatycznie przekształcane w wyrażenia skalarne lub podzapytania skalarne, które są podstawiane w zapytaniu wywołującym zamiast operatora UDF. Te wyrażenia i podzapytania są następnie optymalizowane. W związku z tym plan zapytania nie ma już operatora funkcji zdefiniowanej przez użytkownika, ale jego efekty są obserwowane w planie, takie jak widoki lub wbudowane funkcje wartości tabeli (TVFs).
Przykłady
W przykładach w tej sekcji użyto bazy danych testów porównawczych TPC-H. Aby uzyskać więcej informacji, zobacz TPC-H Homepage.
A. Funkcja skalarna UDF z pojedynczą instrukcją
Rozważ następujące zapytanie.
SELECT L_SHIPDATE,
O_SHIPPRIORITY,
SUM(L_EXTENDEDPRICE * (1 - L_DISCOUNT))
FROM LINEITEM
INNER JOIN ORDERS
ON O_ORDERKEY = L_ORDERKEY
GROUP BY L_SHIPDATE, O_SHIPPRIORITY
ORDER BY L_SHIPDATE;
To zapytanie oblicza sumę obniżonych cen dla pozycji wiersza i przedstawia wyniki pogrupowane według daty wysyłki i priorytetu wysyłki. Wyrażenie L_EXTENDEDPRICE *(1 - L_DISCOUNT)
jest formułą na obniżoną cenę dla danej pozycji. Takie formuły można wyodrębnić do funkcji w celu uzyskania korzyści z modułowości i ponownego użycia.
CREATE FUNCTION dbo.discount_price
(
@price DECIMAL (12, 2),
@discount DECIMAL (12, 2)
)
RETURNS DECIMAL (12, 2)
AS
BEGIN
RETURN @price * (1 - @discount);
END
Teraz można zmodyfikować zapytanie w celu wywołania tej funkcji zdefiniowanej przez użytkownika (UDF).
SELECT L_SHIPDATE,
O_SHIPPRIORITY,
SUM(dbo.discount_price(L_EXTENDEDPRICE, L_DISCOUNT))
FROM LINEITEM
INNER JOIN ORDERS
ON O_ORDERKEY = L_ORDERKEY
GROUP BY L_SHIPDATE, O_SHIPPRIORITY
ORDER BY L_SHIPDATE;
Zapytanie z funkcją zdefiniowaną przez użytkownika ma słabą wydajność ze względu na opisane wcześniej przyczyny. W przypadku wsunięcia funkcji skalarnej UDF, wyrażenie skalarne w ciele funkcji jest zastępowane bezpośrednio w zapytaniu. Wyniki uruchamiania tego zapytania są wyświetlane w poniższej tabeli:
Zapytanie: | Zapytanie bez UDF | Zapytanie z UDF (bez inlining) | Zapytanie z wbudowaną funkcją skalarną UDF |
---|---|---|---|
Czas wykonywania: | 1,6 sekundy | 29 minut 11 sekund | 1,6 sekundy |
Te liczby są oparte na bazie danych 10 GB CCI (przy użyciu schematu TPC-H), działającej na maszynie z podwójnym procesorem (12 rdzeni), 96 GB pamięci RAM, wspieranym przez dysk SSD. Liczby obejmują czas kompilacji i wykonania z zimnym cache'm procedur i pulą buforów. Użyto konfiguracji domyślnej i nie utworzono żadnych innych indeksów.
B. Funkcja skalarna UDF z wieloma instrukcjami
Skalarne funkcje zdefiniowane przez użytkownika, które są implementowane przy użyciu wielu instrukcji języka T-SQL, takich jak przypisania zmiennych i rozgałęzianie warunkowe, mogą być również skomponowane w linii. Rozważmy następującą skalarną funkcję zdefiniowaną przez użytkownika, która na podstawie klucza klienta określa kategorię usługi dla danego klienta. Aby przypisać ją do odpowiedniej kategorii, najpierw obliczamy łączną cenę wszystkich zamówień złożonych przez klienta przy użyciu zapytania SQL. Następnie używa logiki IF (...) ELSE
do decydowania o kategorii na podstawie łącznej ceny.
CREATE OR ALTER FUNCTION dbo.customer_category (@ckey INT)
RETURNS CHAR (10)
AS
BEGIN
DECLARE @total_price AS DECIMAL (18, 2);
DECLARE @category AS CHAR (10);
SELECT @total_price = SUM(O_TOTALPRICE)
FROM ORDERS
WHERE O_CUSTKEY = @ckey;
IF @total_price < 500000
SET @category = 'REGULAR';
ELSE
IF @total_price < 1000000
SET @category = 'GOLD';
ELSE
SET @category = 'PLATINUM';
RETURN @category;
END
Teraz rozważ zapytanie, które wywołuje tę funkcję zdefiniowaną przez użytkownika.
SELECT C_NAME,
dbo.customer_category(C_CUSTKEY)
FROM CUSTOMER;
Plan wykonywania dla tego zapytania w programie SQL Server 2017 (14.x) (poziom zgodności 140 i starszych) jest następujący:
Jak pokazuje plan, program SQL Server przyjmuje tutaj prostą strategię: dla każdej krotki w tabeli CUSTOMER
wywołaj funkcję UDF i wyjmij wyniki. Ta strategia jest naiwna i nieefektywna. W przypadku inliningu takie funkcje zdefiniowane przez użytkownika są przekształcane w równoważne podzapytania skalarne, które są zastępowane w zapytaniu wywołującym zamiast funkcji zdefiniowanej przez użytkownika.
W przypadku tego samego zapytania plan z wbudowaną funkcją zdefiniowaną przez użytkownika wygląda następująco.
Jak wspomniano wcześniej, plan zapytania nie ma już operatora funkcji zdefiniowanej przez użytkownika, ale jego efekty są teraz widoczne w planie, podobnie jak w przypadku widoków lub wbudowanych funkcji TVF. Poniżej przedstawiono niektóre kluczowe obserwacje z poprzedniego planu:
Program SQL Server wywnioskuje niejawne sprzężenia między
CUSTOMER
aORDERS
i udostępnia je jawnie za pośrednictwem operatora sprzężenia.Program SQL Server wywnioskuje również niejawną
GROUP BY O_CUSTKEY on ORDERS
i używa puli IndexSpool + StreamAggregate do jej zaimplementowania.Program SQL Server korzysta teraz z równoległości we wszystkich operatorach.
W zależności od złożoności logiki w UDF, wynikowy plan zapytania może również być większy i bardziej złożony. Jak widać, operacje wewnątrz funkcji zdefiniowanej przez użytkownika nie są już nieprzejrzyste, więc optymalizator zapytań może analizować i optymalizować te operacje. Ponadto, ponieważ funkcja UDF nie znajduje się już w planie, iteracyjne wywołania funkcji UDF są zastępowane przez plan, który całkowicie unika obciążenia wywołania funkcji.
Wymagania wbudowanej skalowalnej funkcji zdefiniowanej przez użytkownika
Skalarna funkcja UDF języka T-SQL może być zainlinowana, jeśli definicja funkcji używa dozwolonych konstrukcji, a funkcja jest używana w kontekście, który umożliwia inlining:
Wszystkie następujące warunki definicji UDF muszą być spełnione:
- Funkcja UDF jest zapisywana przy użyciu następujących konstrukcji:
-
DECLARE
,SET
: deklaracja zmiennej i przypisania. -
SELECT
: zapytanie SQL z pojedynczymi/wieloma przypisaniami zmiennych 1. -
IF
/ELSE
: Rozgałęzianie z dowolnymi poziomami zagnieżdżania. -
RETURN
: Jedna lub więcej instrukcji return. Począwszy od programu SQL Server 2019 (15.x) CU5, funkcja zdefiniowanej przez użytkownika może zawierać tylko jedną instrukcję RETURN, która ma być brana pod uwagę w celu podkreślenia 6. -
UDF
: zagnieżdżone/rekursywne wywołania funkcji 2. - Inne: operacje relacyjne, takie jak
EXISTS
,IS NULL
.
-
- Funkcja zdefiniowana przez użytkownika nie wywołuje żadnej funkcji wewnętrznej, która jest zależna od czasu (na przykład
GETDATE()
) lub ma skutki uboczne 3 (na przykładNEWSEQUENTIALID()
). - Funkcja UDF używa klauzuli
EXECUTE AS CALLER
(zachowanie domyślne, jeśli nie określono klauzuliEXECUTE AS
). - Funkcja UDF nie odwołuje się do zmiennych tabeli ani parametrów z wartościami tabeli.
- Funkcja UDF nie jest natywnie kompilowana (obsługiwana jest interoperacyjność).
- Funkcja UDF nie odwołuje się do typów zdefiniowanych przez użytkownika.
- Do UDF 9nie dodano żadnych podpisów.
- Funkcja UDF nie jest funkcją partycji.
- Funkcja UDF nie zawiera odwołań do wspólnych wyrażeń tabel (CTE).
- Funkcja zdefiniowana przez użytkownika nie zawiera odwołań do funkcji wewnętrznych, które mogą zmieniać wyniki po wstawieniu (np.
@@ROWCOUNT
) 4. - Funkcja zdefiniowana przez użytkownika (UDF) nie zawiera funkcji agregujących, które są przekazywane jako parametry do skalarnej UDF 4.
- Funkcja UDF nie odwołuje się do wbudowanych widoków (takich jak
OBJECT_ID
) 4. - Funkcja UDF nie odwołuje się do metod XML 5.
- Funkcja UDF nie zawiera klauzuli SELECT z
ORDER BY
bez klauzuliTOP 1
5. - Funkcja UDF nie zawiera zapytania SELECT, które wykonuje przypisanie z klauzulą
ORDER BY
(na przykładSELECT @x = @x + 1 FROM table1 ORDER BY col1
) 5. - Funkcja UDF nie zawiera wielu instrukcji typu RETURN 6.
- Funkcja UDF nie odwołuje się do funkcji
STRING_AGG
6. - Funkcja UDF nie odwołuje się do tabel zdalnych 7.
- Funkcja UDF nie odwołuje się do zaszyfrowanych kolumn 8.
- UDF nie zawiera odwołań do
WITH XMLNAMESPACES
8. - Jeśli definicja UDF rozciąga się na tysiące wierszy kodu, SQL Server może zdecydować, że nie zostanie ona wbudowana.
1SELECT
ze zmienną akumulacją/agregacją nie jest obsługiwana w przypadku tworzenia inliningu (na przykład SELECT @val += col1 FROM table1
).
2 rekursywne UDF-y są rozwijane tylko do określonej głębokości.
3 funkcje wewnętrzne, których wyniki zależą od bieżącego czasu systemowego, są zależne od czasu. Funkcja wewnętrzna, która może zaktualizować jakiś wewnętrzny stan globalny, jest przykładem funkcji ze skutkami ubocznymi. Takie funkcje zwracają różne wyniki za każdym razem, gdy są wywoływane, na podstawie stanu wewnętrznego.
4 ograniczenie dodane w SQL Server 2019 (15.x) CU 2
5 ograniczeń dodanych w aktualizacji CU 4 programu SQL Server 2019 (15.x)
Ograniczenie dodane w aktualizacji CU 5 dla programu SQL Server 2019 (15.x)
Ograniczenie dodane w aktualizacji CU 6 programu SQL Server 2019 (15.x)
8 ograniczenie dodane w programie SQL Server 2019 (15.x) CU 11
9 Ponieważ można dodać i usunąć podpisy po utworzeniu funkcji zdefiniowanej przez użytkownika, decyzja o tym, czy wstawić w kod, następuje podczas kompilacji zapytania odwołującego się do skalarnej funkcji użytkownika. Na przykład funkcje systemowe są zwykle podpisane przy użyciu certyfikatu. Aby dowiedzieć się, które obiekty są podpisane, można użyć sys.crypt_properties.
Wszystkie następujące wymagania kontekstu wykonawczego muszą być spełnione:
- Funkcja UDF nie jest używana w klauzuli
ORDER BY
. - Zapytanie wywołujące skalarną funkcję zdefiniowaną przez użytkownika nie odwołuje się do skalarnego wywołania funkcji zdefiniowanej przez użytkownika w klauzuli
GROUP BY
. - Zapytanie wywołujące skalarną funkcję zdefiniowaną przez użytkownika na liście wyboru z klauzulą
DISTINCT
nie zawiera klauzuliORDER BY
. - Funkcja UDF nie jest wywoływana z instrukcji RETURN 1.
- Zapytanie wywołujące funkcję UDF nie ma wspólnych wyrażeń tabelowych (CTE) 3.
- Kwerenda wywołująca UDF nie używa
GROUPING SETS
,CUBE
aniROLLUP
2. - Zapytanie wywołujące funkcję zdefiniowanej przez użytkownika nie zawiera zmiennej, która jest używana jako parametr UDF do przypisania (na przykład
SELECT @y = 2
,@x = UDF(@y)
) 2. - Funkcja UDF nie jest używana w obliczonej kolumnie ani w definicji ograniczenia sprawdzania.
1 ograniczenie dodane w programie SQL Server 2019 (15.x) CU 5
2 ograniczenie dodane w aktualizacji CU 6 programu SQL Server 2019 (15.x)
3 ograniczenie dodane w programie SQL Server 2019 (15.x) CU 11
Aby uzyskać informacje na temat najnowszych poprawek i zmian dotyczących inline'owania funkcji skalarnych zdefiniowanych przez użytkownika języka T-SQL oraz scenariuszy uprawnień do inline'owania, zobacz artykuł z bazy wiedzy: FIX: scalar UDF inlining issues in SQL Server 2019.
Sprawdź, czy funkcja zdefiniowana przez użytkownika może być wbudowana w linie kodu.
Dla każdej skalarnej funkcji zdefiniowanej przez użytkownika w języku T-SQL, widok katalogu sys.sql_modules zawiera właściwość o nazwie is_inlineable
, która wskazuje, czy funkcja UDF jest możliwa do wbudowania.
Właściwość is_inlineable
pochodzi z konstrukcji zawartych wewnątrz definicji funkcji UDF (zdefiniowanej przez użytkownika). Nie sprawdza, czy funkcja UDF jest w rzeczywistości wbudowana w czasie kompilacji. Aby uzyskać więcej informacji, zobacz warunki dla wstawiania .
Wartość 1
wskazuje, że funkcja UDF jest wbudowana, a 0
wskazuje inaczej. Ta właściwość ma również wartość 1
dla wszystkich wbudowanych plików TVF. Dla wszystkich innych modułów wartość to 0
.
Jeśli skalarna funkcja UDF jest możliwa do zagnieżdżenia, nie oznacza to, że zawsze jest zagnieżdżona. Program SQL Server decyduje, na podstawie poszczególnych zapytań i poszczególnych funkcji zdefiniowanych przez użytkownika, czy należy zagnieździć funkcję zdefiniowaną przez użytkownika. Zapoznaj się z listami wymagań we wcześniejszej części tego artykułu.
SELECT b.name,
b.type_desc,
a.is_inlineable
FROM sys.sql_modules AS a
INNER JOIN sys.objects AS b
ON a.object_id = b.object_id
WHERE b.type IN ('IF', 'TF', 'FN');
Sprawdź, czy nastąpiło podkreślenie
Jeśli wszystkie warunki wstępne są spełnione, a program SQL Server zdecyduje się przeprowadzić inlining, przekształca funkcję zdefiniowaną przez użytkownika w wyrażenie relacyjne. W planie zapytania możesz ustalić, czy wystąpiło zagnieżdżanie.
- Kod XML planu nie zawiera węzła XML
<UserDefinedFunction>
dla funkcji zdefiniowanej przez użytkownika, która została poprawnie zintegrowana. - Niektóre zdarzenia rozszerzone są emitowane.
Włącz wbudowywanie skalarnych funkcji UDF
Można sprawić, że obciążenia automatycznie będą kwalifikować się do wbudowywania skalarnych funkcji UDF, aktywując poziom zgodności 150 dla bazy danych. Można to ustawić przy użyciu języka Transact-SQL. Na przykład:
ALTER DATABASE [WideWorldImportersDW]
SET COMPATIBILITY_LEVEL = 150;
Poza tym krokiem nie trzeba wprowadzać żadnych innych zmian w funkcjach zdefiniowanych przez użytkownika lub zapytaniach w celu skorzystania z tej funkcji.
Wyłącz inline'owanie skalarnej funkcji zdefiniowanej przez użytkownika bez zmiany poziomu zgodności
Można wyłączyć wstawianie funkcji skalarnych UDF na poziomie bazy danych, instrukcji lub samej funkcji, nadal utrzymując zgodność poziomu bazy danych na poziomie 150 i wyższym. Aby wyłączyć scalarną funkcję zdefiniowaną przez użytkownika w zakresie bazy danych, wykonaj następującą instrukcję w kontekście odpowiedniej bazy danych:
ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = OFF;
Aby ponownie włączyć scalarną funkcję zdefiniowaną przez użytkownika dla bazy danych, wykonaj następującą instrukcję w kontekście odpowiedniej bazy danych:
ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = ON;
Kiedy ON
, to ustawienie jest wyświetlane jako włączone w sys.database_scoped_configurations.
Można również wyłączyć scalarną funkcję zdefiniowaną przez użytkownika dla określonego zapytania, określając DISABLE_TSQL_SCALAR_UDF_INLINING
jako wskazówkę USE HINT
zapytania.
Wskazówka zapytania USE HINT
ma pierwszeństwo przed konfiguracją zakresu bazy danych lub ustawieniem poziomu zgodności.
Na przykład:
SELECT L_SHIPDATE,
O_SHIPPRIORITY,
SUM(dbo.discount_price(L_EXTENDEDPRICE, L_DISCOUNT))
FROM LINEITEM
INNER JOIN ORDERS
ON O_ORDERKEY = L_ORDERKEY
GROUP BY L_SHIPDATE, O_SHIPPRIORITY
ORDER BY L_SHIPDATE
OPTION (USE HINT('DISABLE_TSQL_SCALAR_UDF_INLINING'));
Scalar UDF inlining można również wyłączyć dla określonej funkcji zdefiniowanej przez użytkownika przy użyciu klauzuli INLINE w instrukcji CREATE FUNCTION
lub ALTER FUNCTION
.
Na przykład:
CREATE OR ALTER FUNCTION dbo.discount_price
(
@price DECIMAL (12, 2),
@discount DECIMAL (12, 2)
)
RETURNS DECIMAL (12, 2)
WITH INLINE = OFF
AS
BEGIN
RETURN @price * (1 - @discount);
END
Po wykonaniu poprzedniej instrukcji ta funkcja zdefiniowana przez użytkownika nigdy nie zostanie zintegrowana do żadnego zapytania, które ją wywołuje. Aby ponownie włączyć wstawianie dla tej UDF, wykonaj następującą instrukcję:
CREATE OR ALTER FUNCTION dbo.discount_price
(
@price DECIMAL (12, 2),
@discount DECIMAL (12, 2)
)
RETURNS DECIMAL (12, 2)
WITH INLINE = ON
AS
BEGIN
RETURN @price * (1 - @discount);
END
Klauzula INLINE
nie jest obowiązkowa. Jeśli klauzula INLINE
nie zostanie określona, zostanie ona automatycznie ustawiona na ON
/OFF
w zależności od tego, czy funkcja zdefiniowana przez użytkownika może być wbudowana. Jeśli INLINE = ON
jest określony, ale funkcja UDF jest niekwalifikowana do tworzenia inliningu, zgłaszany jest błąd.
Uwagi
Zgodnie z opisem w tym artykule, wstawianie skalarnych funkcji zdefiniowanych przez użytkownika przekształca zapytanie zawierające takie funkcje w zapytanie z równoważnym podzapytaniem skalarnym. Ze względu na tę transformację można zauważyć pewne różnice w zachowaniu w następujących scenariuszach:
Podkreślenie powoduje utworzenie innego skrótu zapytania dla tego samego tekstu zapytania.
Niektóre ostrzeżenia w instrukcjach wewnątrz funkcji zdefiniowanej przez użytkownika (takie jak dzielenie przez zero itp.), które mogą być wcześniej ukryte, mogą być wyświetlane z powodu podkreślenia.
Sugestie dotyczące sprzężeń na poziomie zapytania mogą nie być już prawidłowe, ponieważ inline'owanie może wprowadzać nowe sprzężenia. Zamiast tego należy użyć lokalnych wskazówek dotyczących sprzężeń.
Nie można indeksować widoków odwołujących się do skalarnych funkcji wbudowanych zdefiniowanych przez użytkownika. Jeśli musisz utworzyć indeks dla takich widoków, wyłącz liniowe wstawianie dla odwołanych funkcji zdefiniowanych przez użytkownika.
Mogą wystąpić pewne różnice w zachowaniu dynamicznego maskowania danych z wstawianiem UDF.
W niektórych sytuacjach (w zależności od logiki w funkcji zdefiniowanej przez użytkownika) podkreślenie może być bardziej konserwatywne w odniesieniu do maskowania kolumn wyjściowych. W scenariuszach, w których kolumny, do których odwołuje się funkcja UDF, nie są kolumnami wyjściowymi, nie są maskowane.
Jeśli funkcja zdefiniowana przez użytkownika odwołuje się do wbudowanych funkcji, takich jak
SCOPE_IDENTITY()
,@@ROWCOUNT
lub@@ERROR
, wartość zwracana przez te funkcje wbudowane zmienia się podczas wstawiania. Ta zmiana zachowania wynika z faktu, że inlining zmienia zakres instrukcji w ramach UDF. Począwszy od programu SQL Server 2019 (15.x) CU2, tworzenie inliningu jest blokowane, jeśli funkcja zdefiniowana przez użytkownika odwołuje się do niektórych funkcji wewnętrznych (na przykład@@ROWCOUNT
).Jeśli zmienna jest przypisana wynikowi wbudowanej Funkcji Definiowanej przez Użytkownika (UDF), i używana jako
index_column_name
we wskazówkach dotyczących zapytańFORCESEEK
, co powoduje błąd 8622, wskazujący, że procesor zapytań nie może utworzyć planu zapytania z powodu wskazówek zdefiniowanych w zapytaniu.
Powiązana zawartość
- Tworzenie funkcji zdefiniowanych przez użytkownika (aparat bazy danych)
- Performance Center dla aparatu bazy danych SQL Server i usługi Azure SQL Database
- przewodnik po architekturze przetwarzania zapytań
- Odwołanie operatora planu wykonania logicznego i fizycznego
- Łączenia (SQL Server)
- Przedstawianie Inteligentnego Przetwarzania Zapytan
- FIX: problemy z tworzeniem kodu UDF w programie SQL Server 2019