Czy to błąd w SQL Server 2016?
Tak. Zdecydowanie nie jest to właściwe zachowanie. Zgłosiłem to tutaj i został naprawiony w SQL Server 2016 SP2 CU9 .
Jak mówi Mikael Eriksson w komentarzach sys.database_scoped_configurationsi sys.dm_exec_sessionssą realizowane jako widoki w formacie
SELECT ...
FROM OpenRowset(TABLE xxxx)
Jednak porównanie dwóch poniższych planów jest oczywistą różnicą.
DBCC TRACEON(3604);
DECLARE @database_scoped_configurations TABLE(x INT);
INSERT INTO @database_scoped_configurations
SELECT configuration_id
FROM sys.database_scoped_configurations
OPTION (QUERYTRACEON 8608, QUERYTRACEON 8615, QUERYTRACEON 8619, QUERYTRACEON 8620 );
DECLARE @dm_exec_sessions TABLE(x INT);
INSERT INTO @dm_exec_sessions
SELECT session_id
FROM sys.dm_exec_sessions
OPTION (QUERYTRACEON 8608, QUERYTRACEON 8615, QUERYTRACEON 8619, QUERYTRACEON 8620 );

Dane wyjściowe flagi śledzenia 8619 dla obu tych zapytań pokazują
Zastosuj regułę: EnforceHPandAccCard - x0-> Spool or Top (x0)
SQL Server najwyraźniej nie jest w stanie ustalić, czy źródło TVF nie jest również celem wstawiania, więc wymaga ochrony na Halloween.
W przypadku sesji zostało to zaimplementowane jako bufor, który najpierw przechwytuje wszystkie wiersze. W database_scoped_configurationsdodając a TOP 1do planu. Zastosowanie ochrony TOPna Halloween omówiono w tym artykule . W artykule wspomniano również o nieudokumentowanej fladze śledzenia, która wymusza buforowanie, a nie TOPdziała zgodnie z oczekiwaniami.
DECLARE @database_scoped_configurations TABLE(x INT);
INSERT INTO @database_scoped_configurations
SELECT configuration_id
FROM sys.database_scoped_configurations
OPTION (QUERYTRACEON 8692)
Oczywistym problemem związanym z używaniem TOP 1zamiast szpuli jest to, że arbitralnie ogranicza liczbę wstawionych wierszy. Byłoby to prawidłowe tylko wtedy, gdy liczba wierszy zwróconych przez funkcję wynosiła <= 1.
Wstępna notatka wygląda następująco

Porównaj to z początkową notatką dla zapytania 2

Jeśli dobrze rozumiem powyższe, to wydaje się, że pierwszy TVF może zwrócić maksymalnie jeden wiersz i dlatego stosuje niepoprawną optymalizację. Maksimum dla drugiego zapytania jest ustawione na 1.34078E+154( 2^512).
Nie mam pojęcia, skąd pochodzi ta maksymalna liczba wierszy. Być może metadane dostarczone przez autora DMV? Dziwne jest również to, że TOP(50)obejście nie zostało przepisane, TOP(1)ponieważ TOP(50)nie zapobiegłoby wystąpieniu problemu z Halloween (choć zatrzymałoby go na czas nieokreślony)