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

Hurtigste måde at opdatere 120 millioner poster på

Den eneste fornuftige måde at opdatere en tabel med 120 millioner poster på er med en SELECT erklæring, der udfylder et sekund bord. Du skal passe på, når du gør dette. Instruktioner nedenfor.

Simpelt tilfælde

For en tabel uden et klynget indeks, i en tid uden samtidig DML:

  • SELECT *, new_col = 1 INTO clone.BaseTable FROM dbo.BaseTable
  • genskab indekser, begrænsninger osv. på ny tabel
  • skift gammelt og nyt med ALTER SCHEMA ... OVERFØRSEL.
  • slip gammel tabel

Hvis du ikke kan oprette et klonskema, vil et andet tabelnavn i det samme skema gøre det. Husk at omdøbe alle dine begrænsninger og udløsere (hvis relevant) efter skiftet.

Ikke-simpelt tilfælde

Genskab først din BaseTable med samme navn under et andet skema, f.eks. clone.BaseTable . Brug af et separat skema vil forenkle omdøbningsprocessen senere.

  • Medtag det klyngede indeks , hvis relevant. Husk, at primære nøgler og unikke begrænsninger kan være grupperet, men ikke nødvendigvis.
  • Medtag identitetskolonner og beregnede kolonner , hvis det er relevant.
  • Medtag din nye INT-kolonne , hvor end det hører hjemme.
  • Inkluder ikke nogen af ​​følgende:
    • triggere
    • fremmednøglebegrænsninger
    • ikke-klyngede indekser/primære nøgler/unikke begrænsninger
    • check begrænsninger eller standard begrænsninger. Standardindstillinger gør ikke den store forskel, men vi forsøger at holde tingene minimale.

Test derefter din indsats med 1000 rækker:

-- 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øg resultaterne. Hvis alt vises i orden:

  • afkort klontabellen
  • sørg for, at databasen er i bulk-logget eller simpel gendannelsesmodel
  • udfør hele indsættelsen.

Dette vil tage et stykke tid, men ikke nær så lang tid som en opdatering. Når den er fuldført, skal du kontrollere dataene i klontabellen for at sikre, at alt er korrekt.

Genskab derefter alle ikke-klyngede primære nøgler/unikke begrænsninger/indekser og fremmednøglebegrænsninger (i nævnte rækkefølge). Genskab standard og kontroller begrænsninger, hvis det er relevant. Genskab alle udløsere. Genskab hver begrænsning, indeks eller trigger i en separat batch. f.eks.:

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

Til sidst flytter du dbo.BaseTable til et backup-skema og clone.BaseTable til dbo-skemaet (eller hvor din tabel nu skal leve).

-- -- 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
 

Hvis du har brug for at frigøre diskplads, kan du droppe din oprindelige tabel på dette tidspunkt, selvom det kan være klogt at beholde den et stykke tid endnu.

Det er overflødigt at sige, at dette ideelt set er en offline operation. Hvis du har folk, der ændrer data, mens du udfører denne handling, bliver du nødt til at udføre en true-up-operation med skema-omskifteren. Jeg anbefaler at oprette en trigger på dbo.BaseTable at logge al DML til en separat tabel. Aktiver denne trigger, før du starter indsættelsen. I den samme transaktion, som du udfører skemaoverførslen, skal du bruge logtabellen til at udføre en true-up. Test dette først på en delmængde af dataene! Deltaer er nemme at skrue sammen.



  1. Sådan sammenkædes strenge i SQL Server med CONCAT()

  2. Sådan replikeres PostgreSQL-data til eksterne websteder

  3. Brugerdefineret BESTILLING EFTER Forklaring

  4. Skift af Django-projekt fra sqlite3-backend til postgresql mislykkes ved indlæsning af datadump