Proszę spojrzeć na następujące zapytanie SQL:
CREATE TYPE dbo.IN_MEMORY_TABLE_TYPE AS TABLE
(
source_col INT NULL,
target_col INT not NULL
INDEX ix_InMemoryTable NONCLUSTERED (target_col)
)
WITH (MEMORY_OPTIMIZED = ON)
GO
DECLARE
@t dbo.IN_MEMORY_TABLE_TYPE
INSERT @t
(
source_col,
target_col
)
VALUES
(10, 0),
(0, 0)
UPDATE r1
SET
target_col = -1
FROM @t r1
WHERE EXISTS
(
SELECT *
FROM @t r2
WHERE r2.source_col > 0
)
SELECT *
FROM @t
GO
DROP TYPE dbo.IN_MEMORY_TABLE_TYPE
Podczas wykonywania go w programie SQL Server 2014 (12.0.4100.1 X64) UPDATE
kwerenda działa zgodnie z oczekiwaniami i zwracany jest następujący poprawny wynik:
source_col | target_col ---------------------- 10 | -1 0 | -1
Jednak podczas wykonywania na SQL Server 2016 (13.0.4001.0 X64) nie wszystkie wiersze są aktualizowane i zwracane są następujące informacje:
source_col | target_col ---------------------- 10 | -1 0 | 0
Dla mnie to wygląda na błąd, prawda?
sql-server
sql-server-2016
memory-optimized-tables
Dmitrij Savchenko
źródło
źródło
Odpowiedzi:
Tak, jest to błąd, który wydaje się wpływać tylko na zmienne tabeli, z metodą dostępu do indeksu bw-tree i nieskorelowanym samozłączeniem.
Uproszczone repro przy użyciu
DELETE
:Uwaga: w powyższym planie poszukiwanie wierszy do usunięcia kończy się wcześniej niż oczekiwano (tylko dwa wiersze są odczytywane ze skanu). Ochrona Halloween jest ogólnie poprawnie obsługiwana dla OLTP w pamięci, po prostu wydaje się, że istnieje konkretny problem z kombinacją czynników wymienionych powyżej.
Ten błąd został naprawiony w SQL Server 2016 SP1 CU5 i SQL Server 2017 CU1 :
źródło