Comportamiento incorrecto de SQL Server 2016 con tablas con memoria optimizada


13

Eche un vistazo a la siguiente consulta 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

Al ejecutarlo en SQL Server 2014 (12.0.4100.1 X64), UPDATEla consulta se realiza como se esperaba y se devuelve el siguiente resultado válido:

source_col | target_col
----------------------
10 | -1
0 | -1

Sin embargo, cuando se ejecuta en SQL Server 2016 (13.0.4001.0 X64) no se actualizan todas las filas y se devuelve lo siguiente:

source_col | target_col
----------------------
10 | -1
0 | 0 0

Esto me parece un error, ¿te parece así?


Sí, esto es un error. Probado en SQL 2017 CTP 2.1 y se comporta igual que en SQL 2016.
Dean Savović

Respuestas:


12

Sí, es un error, que parece afectar solo las variables de la tabla, con un método de acceso al índice bw-tree y una autounión no correlacionada.

Reproducción simplificada usando DELETE:

CREATE TYPE dbo.IN_MEMORY_TABLE_TYPE AS TABLE
(
    col integer NOT NULL INDEX i NONCLUSTERED (col)
)
WITH (MEMORY_OPTIMIZED = ON);
GO
DECLARE @T AS dbo.IN_MEMORY_TABLE_TYPE;

INSERT @T (col)
VALUES (1), (2), (3), (4), (5);

DELETE T
FROM @T AS T
WHERE EXISTS 
(
    SELECT 1
    FROM @T AS T2
    WHERE T2.col = 1 -- Vary this number 1-5
);

SELECT T.col FROM @T AS T;
GO
DROP TYPE dbo.IN_MEMORY_TABLE_TYPE;

Plan defectuoso

Tenga en cuenta que en el plan anterior la búsqueda de filas para eliminar termina antes de lo esperado (solo se leen dos filas del escaneo). La protección de Halloween generalmente se maneja correctamente para OLTP en memoria, solo parece haber un problema específico con la combinación de factores mencionados anteriormente.


Este error se corrigió en SQL Server 2016 SP1 CU5 y SQL Server 2017 CU1 :

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.