Bellek optimize edilmiş tablolarla SQL Server 2016'nın yanlış davranışı


13

Lütfen aşağıdaki SQL sorgusuna bir göz atın:

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'te (12.0.4100.1 X64) yürütülürken UPDATE, sorgudaki sorgu beklendiği gibi çalışır ve aşağıdaki geçerli sonuç döndürülür:

kaynak_kol | target_col
----------------------
10 | -1
0 | -1

Ancak, SQL Server 2016'da (13.0.4001.0 X64) yürütülürken tüm satırlar güncellenmez ve aşağıdakiler döndürülür:

kaynak_kol | target_col
----------------------
10 | -1
0 | 0

Bu benim için bir hata gibi görünüyor, sana öyle görünüyor mu?


Evet, bu bir hata. SQL 2017 CTP 2.1 üzerinde test edildi ve SQL 2016'da olduğu gibi çalışıyor.
Dean Savović

Yanıtlar:


12

Evet, bw-tree dizin erişim yöntemi ve ilişkisiz kendi kendine birleştirme ile yalnızca tablo değişkenlerini etkiliyor gibi görünen bir hatadır.

Aşağıdakileri kullanarak basitleştirilmiş repro 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;

Hatalı plan

Yukarıdaki planda, silinecek satır aramasının beklenenden daha erken sonlandığına dikkat edin (taramadan yalnızca iki satır okunur). Cadılar Bayramı Koruması, Bellek İçi OLTP için genellikle doğru şekilde ele alınır, yukarıda belirtilen faktörlerin kombinasyonu ile ilgili belirli bir sorun var gibi görünüyor.


Bu hata olduğunu sabit içinde SQL Server 2016 SP1 5 PB ve SQL Server 2017 CU1 :

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.