메모리 최적화 테이블을 사용한 SQL Server 2016의 잘못된 동작


13

다음 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

SQL Server 2014 (12.0.4100.1 X64) UPDATE에서 실행하면 쿼리에서 in이 예상대로 수행되고 다음과 같은 유효한 결과가 반환됩니다.

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

그러나 SQL Server 2016 (13.0.4001.0 X64)에서 실행할 때 모든 행이 업데이트되는 것은 아니며 다음이 반환됩니다.

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

이것은 나에게 버그처럼 보인다.


예, 이것은 버그입니다. CTP 2.1 SQL 2017에 그것을 테스트하고 SQL 2016과 마찬가지로 동일한 동작
딘 Savović

답변:


12

그렇습니다. 버그는 bw-tree 인덱스 액세스 방법과 상관없는 자체 조인으로 테이블 변수에만 영향을 미치는 것으로 보입니다.

다음을 사용하여 단순화 된 재현 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;

잘못된 계획

위 계획에서 삭제할 행 검색이 예상보다 빨리 종료됩니다 (스캔에서 두 행만 읽음). 할로윈 보호는 일반적으로 In-Memory OLTP에 대해 올바르게 처리되며 위에서 언급 한 여러 요인의 조합에 특정한 문제가있는 것 같습니다.


이 버그는 SQL Server 2016 SP1 CU5SQL Server 2017 CU1 에서 수정 되었습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.