sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server Bulk Insert – Del 2

I den forrige del af denne artikel diskuterede vi, hvordan man importerer CSV-filer til SQL Server ved hjælp af BULK INSERT-sætning. Vi diskuterede hovedmetoden for bulkinsert-processen og også detaljerne om BATCHSIZE og MAXERRORS muligheder i scenarier. I denne del vil vi gennemgå nogle andre muligheder (FIRE_TRIGGERS, CHECK_CONSTRAINTS og TABLOCK) for masseindsættelsesprocessen i forskellige scenarier.

Scenario 1:Kan vi aktivere triggere i destinationstabellen under masseindsættelsesoperationen?

Som standard udløses de indsættelsesudløsere, der er angivet i måltabellen, under bulkinsert-processen, men i nogle situationer vil vi måske aktivere disse triggere. En løsning på dette problem er at bruge indstillingen FIRE_TRIGGERS i bulk insert-sætninger. Jeg vil tilføje en meddelelse om, at denne mulighed kan påvirke og reducere bulk-indsættelsesoperationens ydeevne, fordi trigger/triggere kan udføre separate operationer i databasen. I det følgende eksempel vil vi demonstrere dette. Til at begynde med vil vi ikke indstille FIRE_TRIGGERS-parameteren, og masseindsættelsesprocessen udløser ikke indsættelsesudløseren. I det følgende T-SQL-script definerer vi en insert-trigger for salgstabellen.

DROP TABEL HVIS FINDER Salg OPRET TABEL [dbo].[Salg]( [Region] [varchar](50) , [Land] [varchar](50) , [ItemType] [varchar](50) NULL, [ SalesChannel] [varchar](50) NULL, [OrderPriority] [varchar](50) NULL, [OrderDate] datetime, [OrderID] bigint NULL, [ShipDate] datetime, [UnitsSold] float, [UnitPrice] float, [UnitCost] float, [TotalRevenue] float, [TotalCost] float, [TotalProfit] float) DROP TABLE IF EXISTS SalesLogCREATE TABEL SalesLog (OrderIDLog bigint)GOCREATE TRIGGER OrdreLogIns ON SalesFOR INSERTASBEGIN SET INCOUNT ON SalesLogINSERT'0CREATE TABEL ON SalesLogINSERT'0CREATE INCOUNT ON SalesLogInS0 Sales Records.csv'WITH (FIRSTROW =2, FIELDTERMINATOR =',', ROWTERMINATOR='\n' ); VÆLG Antal(*) FRA SalesLog

Som du kan se ovenfor, udløste indsættelsesudløseren ikke, fordi vi ikke indstillede FIRE_TRIGGERS-indstillingen. Nu vil vi tilføje indstillingen FIRE_TRIGGERS til bulk insert-sætningen, så denne mulighed gør det muligt at indsætte en brandudløser.

BULK INSERT SalesFROM 'C:\1500000 Sales Records.csv'WITH (FIRSTROW =2, FIELDTERMINATOR =',', ROWTERMINATOR='\n',FIRE_TRIGGERS);GOSELECT tæller(*) som [NumberOfRowsin SalgLog  

Scenario 2:Hvordan kan en kontrolbegrænsning aktiveres under bulk-indsættelsesoperationen?

Check-begrænsninger giver os mulighed for at håndhæve dataintegritet i SQL Server-tabeller. Formålet med begrænsningen er at kontrollere indsatte, opdaterede eller slettede værdier i henhold til deres syntaksregulering. Som f.eks. NOT NULL-begrænsningen giver, at en specificeret kolonne ikke kan ændres af NULL-værdien. Nu vil vi fokusere på begrænsninger og bulkinsert-interaktion. Som standard ignoreres enhver kontrol- og fremmednøglebegrænsning under bulk-indsættelsesprocessen, men denne mulighed har nogle undtagelser. Ifølge Microsoft-dokumentationen "UNIKKE og PRIMÆRE NØGLE-begrænsninger håndhæves altid. Ved import til en tegnkolonne  for hvilken NOT NULL-begrænsningen er defineret, indsætter BULK INSERT en tom streng, når der ikke er nogen værdi i tekstfilen." I det følgende T-SQL-script tilføjer vi en kontrolbegrænsning til kolonnen OrderDate, som kontrollerer ordredatoen, der er større end 01.01.2016.

DROP TABEL HVIS FINDER Salg OPRET TABEL [dbo].[Salg]( [Region] [varchar](50) , [Land] [varchar](50) , [ItemType] [varchar](50) NULL, [ SalesChannel] [varchar](50) NULL, [OrderPriority] [varchar](50) NULL, [OrderDate] datetime, [OrderID] bigint NULL, [ShipDate] datetime, [UnitsSold] float, [UnitPrice] float, [UnitCost] float, [TotalRevenue] float, [TotalCost] float, [TotalProfit] float) ALTER TABLE [Salg] ADD CONSTRAINT OrderDate_CheckCHECK(OrderDate>'20160101')BULK INSERT SalesFROM 'C:\1500000 Sales Records' (20160101') , FIELDTERMINATOR =',', ROWTERMINATOR='\n' );GOSELECT COUNT(*) SOM [UnChekedData] FRA Salg WHERE OrderDate <'20160101'

Som du kan se i ovenstående eksempel, springer masseindsættelsesprocessen kontrolbegrænsningskontrollen over. SQL Server angiver dog kontrolbegrænsning som ikke-tillid.

SELECT is_not_trusted ,* FROM sys.check_constraints where name='OrderDate_Check'

Denne værdi angiver, at nogen har indsat eller opdateret nogle data til denne kolonne ved at springe kontrolbetingelsen over, samtidig med at denne kolonne kan indeholde inkonsistente data med henvisning til denne restriktion. Nu vil vi prøve at udføre bulk insert-sætningen med CHECK_CONSTRAINTS-indstillingen. Resultatet er meget enkelt, check constraint returnerer en fejl på grund af ukorrekte data.

BULK INSERT SalesFRA 'C:\1500000 Sales Records.csv'WITH (FIRSTROW =2, FIELDTERMINATOR =',', ROWTERMINATOR='\n' );

Scenario 3:Hvordan øger man ydeevnen i flere bulk-indsæt i én destinationstabel?

Hovedformålet med låsemekanismen i SQL Server er at beskytte og sikre dataintegriteten. I artiklen Hovedkoncept for SQL Server-låsning kan du finde detaljer om låsemekanisme. Nu vil vi fokusere på bulk-indsatsproceslåsedetaljer. Hvis du kører bulk insert-sætningen uden TABLELOCK-indstillingen, erhverver den låsen af ​​rækker eller tabel i henhold til låsehierarki. Men i nogle tilfælde vil vi måske udføre flere bulk-indsættelsesprocesser mod én destinationstabel, så vi kan reducere driftstiden for masseindsættelsen. Først vil vi udføre to bulk insert-sætninger samtidigt og analysere låsemekanismens opførsel. Vi åbner to forespørgselsvinduer i SQL Server Management Studio og kører følgende bulk insert-sætninger samtidigt.

BULK INSERT SalesFRA 'C:\1500000 Sales Records.csv'WITH (FIRSTROW =2, FIELDTERMINATOR =',', ROWTERMINATOR='\n' );

Når vi udfører følgende dmv-forespørgsel (Dynamic Management View), som hjælper med at overvåge status for masseindsættelsesprocessen.

SELECT session_id,command ,status,last_wait_type,text FROM sys.dm_exec_requests cross apply sys.dm_exec_sql_text(sys.dm_exec_requests.sql_handle)hvor tekst som '%BULK INSERT Sales%' og session_id
@SP>

Som du kan se på ovenstående billede, session 61, er bulkinsert-processtatus suspenderet på grund af låsning. Hvis vi verificerer problemet, låser session 59 destinationstabellen for masseindsættelse, og session 61 venter på frigivelse af denne lås for at fortsætte masseindsættelsesprocessen. Nu vil vi tilføje TABLOCK-indstillingen til bulk-indsæt-sætningerne og udføre forespørgslerne.

Når vi udfører dmv-overvågningsforespørgslen igen, kan vi ikke se nogen suspenderet masseindsættelsesproces, fordi SQL Server bruger en speciel låsetype kaldet bulk update lock (BU). Denne låsetype gør det muligt at behandle flere bulkinsert-operationer mod den samme tabel samtidigt, og denne mulighed reducerer også den samlede tid af bulk-indsættelsesprocessen.

Når vi udfører følgende forespørgsel under masseindsættelsesprocessen, kan vi overvåge låsedetaljerne og låsetyperne.

VÆLG dm_tran_locks.request_session_id, dm_tran_locks.resource_database_id, DB_NAME(dm_tran_locks.resource_database_id) AS dbname, CASE WHEN resource_type ='OBJECT' THEN OBJECT_NAME(dm_tran_partitions_locks.Objektid_tilknyttede.partitions_locks.OBJECT_NAME)ENDJECT_NAVN. indexes.name AS index_name, dm_tran_locks.resource_type, dm_tran_locks.resource_description, dm_tran_locks.resource_associated_entity_id, dm_tran_locks.request_mode, dm_tran_locks.request_statusFROM sys.dm_tran_locksLEFT JOIN sys.partitions ON partitions.hobt_id =dm_tran_locks.resource_associated_entity_idLEFT JOIN sys.indexes ON indexes.OBJECT_ID =partitions .OBJECT_ID AND indexes.index_id =partitions.index_idWHERE resource_associated_entity_id> 0 OG resource_database_id =DB_ID()

Konklusion

I denne artikel undersøgte vi alle detaljer om bulkinsert-operation i SQL Server. Vi nævnte især BULK INSERT-kommandoen og dens indstillinger og muligheder, og vi analyserede også forskellige scenarier, der er tæt på problemer i det virkelige liv.

 

Referencer

BULK INSERT (Transact-SQL)

Forudsætninger for minimal logning i masseimport

Kontrol af låseadfærd for masseimport

Yderligere læsning

Eksport af data til flad fil med BCP Utility og import af data med Bulk Insert

Nyttigt værktøj:

dbForge Data Pump – et SSMS-tilføjelsesprogram til at fylde SQL-databaser med eksterne kildedata og migrere data mellem systemer.


  1. SQL:Parse kommasepareret streng og brug som join

  2. Mysql rækkefølge efter specifikke ID-værdier

  3. Hurtigste måde at opdatere 120 millioner poster på

  4. Sådan bruges ora_hash på en kolonne med datatype xmltype