Veuillez consulter la requête SQL suivante:
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
Lors de son exécution sur SQL Server 2014 (12.0.4100.1 X64), UPDATE
la requête s'exécute comme prévu et le résultat valide suivant est renvoyé:
source_col | target_col ---------------------- 10 | -1 0 | -1
Cependant, lors de l'exécution sur SQL Server 2016 (13.0.4001.0 X64), toutes les lignes ne sont pas mises à jour et ce qui suit est renvoyé:
source_col | target_col ---------------------- 10 | -1 0 | 0
Cela ressemble à un bug pour moi, est-ce que ça vous ressemble?
sql-server
sql-server-2016
memory-optimized-tables
Dmitry Savchenko
la source
la source
Réponses:
Oui, c'est un bogue, qui semble n'affecter que les variables de table, avec une méthode d'accès à l'index bw-tree et une auto-jointure non corrélée.
Repro simplifié utilisant
DELETE
:Notez dans le plan ci-dessus que la recherche de lignes à supprimer se termine plus tôt que prévu (seules deux lignes sont lues à partir de l'analyse). La protection Halloween est généralement correctement gérée pour l'OLTP en mémoire, il semble qu'il y ait juste un problème spécifique avec la combinaison des facteurs mentionnés ci-dessus.
Ce bogue est résolu dans SQL Server 2016 SP1 CU5 et SQL Server 2017 CU1 :
la source