Sample Header Ad - 728x90

Why MERGE doesn't insert more than 277 records into a table which is configured with temporal table and a non-clustered index on history table

25 votes
1 answer
2599 views
I found again an issue with SQL Server and MERGE statement and need some confirmation. I can reproduce my issue constantly on a Azure Database (but not on a on premise SQL Server 2017/2019). Please execute following steps (step by step, not in one command execution)! **1) Script for Schema:**
CREATE TABLE [dbo].[ImpactValueHistory]
	(
		[Rn] BIGINT NOT NULL,

		[ImpactId] UNIQUEIDENTIFIER NOT NULL,
		[ImpactValueTypeId] INT NOT NULL,

		[Date] DATE NOT NULL,
		[Value] DECIMAL(38, 10) NOT NULL,

		[ValidFrom] DATETIME2 NOT NULL CONSTRAINT [DF_ImpactValueHistory_ValidFrom] DEFAULT CONVERT(DATETIME2, '0001-01-01'),
		[ValidTo] DATETIME2 NOT NULL CONSTRAINT [DF_ImpactValueHistory_ValidTo] DEFAULT CONVERT(DATETIME2, '9999-12-31 23:59:59.9999999'),

		[ImpactPeriodId] INT NOT NULL,

		[NormalizedValue] DECIMAL(38, 10) NOT NULL,
	)
	GO

	CREATE CLUSTERED COLUMNSTORE INDEX [COLIX_ImpactValueHistory]
		ON [dbo].[ImpactValueHistory];
	GO

	CREATE NONCLUSTERED INDEX [IX_ImpactValueHistory_ValidFrom_ValidTo_ImpactId_DimensionItemId]
		ON [dbo].[ImpactValueHistory] ([ValidFrom], [ValidTo], [ImpactId], [ImpactValueTypeId], [Date]);
	GO


	CREATE TABLE [dbo].[ImpactValue]
	(
		[Rn] BIGINT NOT NULL IDENTITY(1,1),

		[ImpactId] UNIQUEIDENTIFIER NOT NULL,
		[ImpactValueTypeId] INT NOT NULL,

		[Date] DATE NOT NULL,
		[Value] DECIMAL(38, 10) NOT NULL,

		[ValidFrom] DATETIME2 GENERATED ALWAYS AS ROW START NOT NULL CONSTRAINT [DF_ImpactValue_ValidFrom] DEFAULT CONVERT(DATETIME2, '0001-01-01'),
		[ValidTo] DATETIME2 GENERATED ALWAYS AS ROW END NOT NULL CONSTRAINT [DF_ImpactValue_ValidTo] DEFAULT CONVERT(DATETIME2, '9999-12-31 23:59:59.9999999'),

		[ImpactPeriodId] INT NOT NULL,

		[NormalizedValue] DECIMAL(38, 10) NOT NULL,

		PERIOD FOR SYSTEM_TIME ([ValidFrom], [ValidTo]),

		CONSTRAINT [PK_ImpactValue] PRIMARY KEY NONCLUSTERED ([ImpactId], [ImpactValueTypeId], [Date], [ImpactPeriodId])
	)
	WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[ImpactValueHistory]))
	GO

	CREATE UNIQUE CLUSTERED INDEX [IX_ImpactValue_Id] ON [dbo].[ImpactValue]([Rn])
	GO

	CREATE COLUMNSTORE INDEX [CIX_ImpactValue] ON [dbo].[ImpactValue] ([ImpactId], [ImpactValueTypeId], [Date], [Value], [NormalizedValue])
	GO
**2) Script for inserting some random data** ``` DECLARE @inserted0 TABLE ([Date] DATE, [ImpactId] uniqueidentifier, [ImpactPeriodId] int, [ImpactValueTypeId] int); MERGE [dbo].[ImpactValue] USING ( SELECT TOP 278 -- it's then working 2) If I delete the non-clustered index [IX_ImpactValueHistory_ValidFrom_ValidTo_ImpactId_DimensionItemId] -> it's working 3) If I use SELECT TOP (@BatchSize) in step 2) --> it's working 4) If I use only OUTPUT instead of OUTPUT INTO @inserted0 --> it's working Without the COLUMNSTORE index on the history table it is working. By only removing the COLUMNSTORE index on the main table I see the same issue. Actual execution plan for a case that (a) repros the issue with TOP 278 and (b) doesn't repro with TOP (@BatchSize) available at https://1drv.ms/u/s!AsOa6e9ukBWQlIRg9_9eySDFp5hvEA?e=KBQBsP . I also added the actual execution plans for batch size of 277. Both are working with this size!
Asked by Daniel C. (353 rep)
Jun 20, 2022, 01:34 PM
Last activity: Nov 16, 2024, 08:18 AM