[replaced the initial placed code in the question. I thought the use of a FKHelper would increase speed, but it didn't. See sepupic his comment. Here is my first used code en schema, before the use of FKHelper]
I have a table for a client which has a couple of million rows (about 8-10). I need to use some kind of Insert Ignore and or On Duplicate Key update statements like MySQL has.
This is the table:
USE [BackOffice]
GO
/****** Object: Table [BackOffice].[EsmaInstrumentsTable] Script Date: 2019-11-12 15:35:01 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [BackOffice].[EsmaInstrumentsTable](
[Isin] [varchar](12) NOT NULL,
[FullName] [varchar](254) NULL,
[ShortName] [varchar](128) NULL,
[CFICode] [varchar](6) NOT NULL,
[Currency] [varchar](3) NOT NULL,
[ISOExchangeName] [varchar](4) NOT NULL,
[FirstTradeDT] [datetime2](7) NOT NULL,
[LastTradeDT] [datetime2](7) NOT NULL,
[ExpiryDT] [datetime2](7) NOT NULL,
[Multiplier] [decimal](16, 8) NOT NULL,
[OptionType] [varchar](4) NOT NULL,
[ExerciseStyle] [varchar](6) NOT NULL,
[DeliveryType] [varchar](20) NOT NULL,
[StrikePrice] [decimal](16, 6) NOT NULL,
[UnderLyingISIN] [varchar](12) NOT NULL,
[CompanyCountry] [varchar](2) NULL,
[InstrTerminated] [tinyint] NULL,
CONSTRAINT [EsmaInstrumentsTablePrimaryKey] PRIMARY KEY CLUSTERED
(
[Isin] ASC,
[CFICode] ASC,
[ISOExchangeName] ASC,
[ExpiryDT] ASC,
[StrikePrice] ASC,
[Currency] ASC,
[UnderLyingISIN] ASC,
[OptionType] ASC,
[ExerciseStyle] ASC,
[DeliveryType] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Because I wanted to reduce the searches in columns, I made a "PKHelper" column. This is the Primary Key.
as a trigger I made:
USE [BackOffice]
GO
/****** Object: Trigger [BackOffice].[CheckBeforeInsertOnEsmaInstrumentsTable] Script Date: 2019-11-12 15:38:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create TRIGGER [BackOffice].[CheckBeforeInsertOnEsmaInstrumentsTable] on [BackOffice].[EsmaInstrumentsTable]
instead of INSERT
AS
BEGIN
SET NOCOUNT ON
MERGE
INTO BackOffice.EsmaInstrumentsTable _old
USING inserted _new
ON
_new.Isin = _old.Isin
and
_new.ExpiryDT = _old.ExpiryDT
and
_new.StrikePrice = _old.StrikePrice
and
ISNULL(_new.Currency,'') = ISNULL(_old.Currency,'')
and
ISNULL(_new.CFICode,'') = ISNULL(_old.CFICode,'')
and
ISNULL(_new.OptionType,'') = ISNULL(_old.OptionType,'')
and
ISNULL(_new.ExerciseStyle,'') = ISNULL(_old.ExerciseStyle,'')
and
ISNULL(_new.DeliveryType,'') = ISNULL(_old.DeliveryType,'')
and
ISNULL(_new.ISOExchangeName,'') = ISNULL(_old.ISOExchangeName,'')
WHEN NOT MATCHED THEN
INSERT (Isin,FullName,ShortName,CFICode,Currency,ISOExchangeName,FirstTradeDT,LastTradeDT,ExpiryDT,Multiplier,OptionType,ExerciseStyle,DeliveryType,StrikePrice,UnderLyingISIN,CompanyCountry,InstrTerminated)
VALUES (Isin,FullName,ShortName,CFICode,Currency,ISOExchangeName,FirstTradeDT,LastTradeDT,ExpiryDT,Multiplier,OptionType,ExerciseStyle,DeliveryType,StrikePrice,UnderLyingISIN,CompanyCountry,InstrTerminated)
WHEN MATCHED THEN
Update set
_old.FullName = ISNULL(_new.FullName,_old.FullName),
_old.ShortName = ISNULL(_new.ShortName,_old.ShortName),
_old.FirstTradeDT = ISNULL(_new.FirstTradeDT,_old.FirstTradeDT),
_old.LastTradeDT = ISNULL(_new.LastTradeDT,_old.LastTradeDT),
_old.UnderLyingISIN = ISNULL(_new.UnderLyingISIN,_old.UnderLyingISIN),
_old.CompanyCountry = ISNULL(_new.CompanyCountry,_old.CompanyCountry),
_old.InstrTerminated = ISNULL(_new.InstrTerminated,_old.InstrTerminated);
END;
And my insert statement looks like this
WITH NewData AS
(SELECT * FROM (VALUES
('FRENX4805854','POAS1.2003.03656.C','ENXT FR/O 20200320 C A ALS 36.56','OCASPS','EUR','XMON','2019-03-18 01:00:00.000','2020-03-20 17:30:00.000','2020-03-20 00:00:00.000',100,'CALL','AMER','PHYS',36.56,'FR0010220475','FR',0)
-- up to 2500 rows
) x
(Isin,FullName,ShortName,CFICode,Currency,ISOExchangeName,FirstTradeDT,LastTradeDT,ExpiryDT,Multiplier,OptionType,ExerciseStyle,DeliveryType,StrikePrice,UnderLyingISIN,CompanyCountry,InstrTerminated)
) INSERT INTO
EsmaInstrumentsTableNew(Isin,FullName,ShortName,CFICode,Currency,ISOExchangeName,FirstTradeDT,LastTradeDT,ExpiryDT,Multiplier,OptionType,ExerciseStyle,DeliveryType,StrikePrice,UnderLyingISIN,CompanyCountry,InstrTerminated) SELECT Isin,FullName,ShortName,CFICode,Currency,ISOExchangeName,FirstTradeDT,LastTradeDT,ExpiryDT,Multiplier,OptionType,ExerciseStyle,DeliveryType,StrikePrice,UnderLyingISIN,CompanyCountry,InstrTerminated
FROM NewData
I use this way of inserting, to be able to add more than 1000 rows per statement (limit is set at 1000) Unfortunately this takes quite a while. any suggestions to speed thinks up? (CPU is always around 12.5% on a 4 Core 8 Logical processors machine. and 100/8 is 12.5)
kind regards,
Matthijs