sql >> Databasteknik >  >> RDS >> Sqlserver

Snabbaste sättet att uppdatera 120 miljoner rekord

Det enda vettiga sättet att uppdatera en tabell med 120 miljoner poster är med en SELECT uttalande som fyller en sekund tabell. Du måste vara försiktig när du gör detta. Instruktioner nedan.

Enkelt fall

För en tabell utan ett klustrat index, under en tid utan samtidig DML:

  • SELECT *, new_col = 1 INTO clone.BaseTable FROM dbo.BaseTable
  • återskapa index, begränsningar, etc på ny tabell
  • byt gammalt och nytt med ALTER SCHEMA ... ÖVERFÖRING.
  • släpp gammal tabell

Om du inte kan skapa ett klonschema, fungerar ett annat tabellnamn i samma schema. Kom ihåg att byta namn på alla dina begränsningar och utlösare (om tillämpligt) efter bytet.

Icke-enkelt fall

Återskapa först din BaseTable med samma namn under ett annat schema, t.ex. clone.BaseTable . Om du använder ett separat schema förenklas byteprocessen senare.

  • Inkludera det klustrade indexet , om tillämpligt. Kom ihåg att primärnycklar och unika begränsningar kan vara klustrade, men inte nödvändigtvis.
  • Inkludera identitetskolumner och beräknade kolumner , om tillämpligt.
  • Inkludera din nya INT-kolumn , var den än hör hemma.
  • Inkludera inte något av följande:
    • utlösare
    • restriktioner för främmande nyckel
    • icke-klustrade index/primära nycklar/unika begränsningar
    • kontrollera begränsningar eller standardbegränsningar. Standardinställningar gör inte så stor skillnad, men vi försöker hålla saker och ting minimala.

Testa sedan din infogning med 1000 rader:

-- assuming an IDENTITY column in BaseTable
SET IDENTITY_INSERT clone.BaseTable ON
GO
INSERT clone.BaseTable WITH (TABLOCK) (Col1, Col2, Col3)
SELECT TOP 1000 Col1, Col2, Col3 = -1
FROM dbo.BaseTable
GO
SET IDENTITY_INSERT clone.BaseTable OFF

Undersök resultaten. Om allt visas i ordning:

  • trunkera klontabellen
  • se till att databasen är inloggad i bulk eller enkel återställningsmodell
  • utför hela infogningen.

Detta kommer att ta ett tag, men inte alls lika länge som en uppdatering. När det är klart, kontrollera data i klontabellen för att se till att allt är korrekt.

Återskapa sedan alla icke-klustrade primärnycklar/unika begränsningar/index och främmande nyckelbegränsningar (i den ordningen). Återskapa standard och kontrollera begränsningar, om tillämpligt. Återskapa alla triggers. Återskapa varje begränsning, index eller trigger i en separat batch. t.ex.:

ALTER TABLE clone.BaseTable ADD CONSTRAINT UQ_BaseTable UNIQUE (Col2)
GO
-- next constraint/index/trigger definition here

Flytta slutligen dbo.BaseTable till ett backupschema och clone.BaseTable till dbo-schemat (eller varhelst din tabell är tänkt att bo).

-- -- perform first true-up operation here, if necessary
-- EXEC clone.BaseTable_TrueUp
-- GO
-- -- create a backup schema, if necessary
-- CREATE SCHEMA backup_20100914
-- GO
BEGIN TRY
  BEGIN TRANSACTION
  ALTER SCHEMA backup_20100914 TRANSFER dbo.BaseTable
  -- -- perform second true-up operation here, if necessary
  -- EXEC clone.BaseTable_TrueUp
  ALTER SCHEMA dbo TRANSFER clone.BaseTable
  COMMIT TRANSACTION
END TRY
BEGIN CATCH
  SELECT ERROR_MESSAGE() -- add more info here if necessary
  ROLLBACK TRANSACTION
END CATCH
GO

Om du behöver frigöra diskutrymme kan du släppa din ursprungliga tabell nu, även om det kan vara klokt att behålla det ett tag till.

Det behöver inte sägas att detta är idealiskt offline drift. Om du har personer som ändrar data medan du utför den här operationen måste du utföra en sanningsoperation med schemaväxeln. Jag rekommenderar att du skapar en utlösare på dbo.BaseTable för att logga all DML till en separat tabell. Aktivera denna utlösare innan du startar infogningen. Sedan använder du loggtabellen i samma transaktion som du utför schemaöverföringen för att utföra en sanning. Testa detta först på en delmängd av data! Deltas är lätta att skruva upp.



  1. Vad är Check Constraint i SQL Server - SQL Server / TSQL Tutorial Del 82

  2. Architecting for Security:En guide för MySQL

  3. SQL Server-fel vid uppdateringskommando - Ett allvarligt fel inträffade på det aktuella kommandot

  4. Hur TAN() fungerar i MariaDB