Jediný rozumný způsob aktualizace tabulky 120 milionů záznamů je pomocí SELECT
příkaz, který vyplní sekundu stůl. Když to děláte, musíte být opatrní. Pokyny níže.
Jednoduchý případ
Pro tabulku bez seskupeného indexu během doby bez souběžného DML:
SELECT *, new_col = 1 INTO clone.BaseTable FROM dbo.BaseTable
- znovu vytvořit indexy, omezení atd. v nové tabulce
- přepnout staré a nové pomocí ALTER SCHEMA ... PŘENOS.
- zahodit starý stůl
Pokud nemůžete vytvořit schéma klonu, postačí jiný název tabulky ve stejném schématu. Nezapomeňte po přepnutí přejmenovat všechna svá omezení a spouštěče (pokud jsou k dispozici).
Nejednoduchý případ
Nejprve znovu vytvořte BaseTable
se stejným názvem pod jiným schématem, např. clone.BaseTable
. Použití samostatného schématu později zjednoduší proces přejmenování.
- Zahrňte seskupený index , je-li to relevantní. Pamatujte, že primární klíče a jedinečná omezení mohou být seskupená, ale ne nutně.
- Zahrňte sloupce identity a vypočítané sloupce , je-li to relevantní.
- Zahrňte svůj nový sloupec INT , kamkoli patří.
- Nezahrnujte kteroukoli z následujících možností:
- spouštěče
- cizí klíčová omezení
- neshlukované indexy/primární klíče/jedinečná omezení
- zkontrolujte omezení nebo výchozí omezení. Ve výchozích nastaveních se příliš neliší, ale snažíme se, aby byly věci minimální.
Poté otestujte svou přílohu s 1000 řádky:
-- 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
Prozkoumejte výsledky. Pokud je vše v pořádku:
- zkrátit tabulku klonů
- ujistěte se, že databáze je v hromadném nebo jednoduchém modelu obnovení
- proveďte úplné vložení.
Bude to chvíli trvat, ale ne tak dlouho jako aktualizace. Po dokončení zkontrolujte data v klonovací tabulce, abyste se ujistili, že je vše v pořádku.
Poté znovu vytvořte všechny neklastrované primární klíče/jedinečná omezení/indexy a omezení cizích klíčů (v tomto pořadí). Znovu vytvořte výchozí a případně zkontrolujte omezení. Znovu vytvořte všechny spouštěče. Znovu vytvořte každé omezení, index nebo spouštěč v samostatné dávce. např.:
ALTER TABLE clone.BaseTable ADD CONSTRAINT UQ_BaseTable UNIQUE (Col2)
GO
-- next constraint/index/trigger definition here
Nakonec přesuňte dbo.BaseTable
na záložní schéma a clone.BaseTable
do schématu dbo (nebo kdekoli, kde má váš stůl žít).
-- -- 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
Pokud potřebujete uvolnit místo na disku, můžete svou původní tabulku v tuto chvíli zahodit, i když může být rozumné ponechat si ji ještě chvíli.
Netřeba dodávat, že v ideálním případě se jedná o offline úkon. Pokud máte lidi, kteří během provádění této operace upravují data, budete muset provést operaci ověření pomocí přepínače schématu. Doporučuji vytvořit spouštěč na dbo.BaseTable
pro přihlášení všech DML do samostatné tabulky. Povolte tuto spoušť před spuštěním vkládání. Poté ve stejné transakci, jakou provádíte přenos schématu, použijte tabulku protokolu k provedení oprav. Nejprve to otestujte na podmnožině dat! Delty lze snadno pokazit.