Aumentare la colonna di modifica della velocità sulla tabella di grandi dimensioni su NON NULL


12

Di recente ho aggiunto una colonna di bit in grado NULL a una tabella che ha quasi 500 milioni di righe. Non c'è un valore predefinito nella colonna, tuttavia tutti gli inserti specificano un valore pari a 0 o 1 e ho eseguito una routine una tantum per assegnare 0 o 1 a tutte le righe esistenti (aggiornando le righe in piccoli lotti). Ogni riga dovrebbe ora avere uno 0 o 1 in quella colonna.

Voglio rendere la colonna di bit non annullabile tuttavia quando ho provato a farlo tramite ALTER TABLE t1 ALTER COLUMN c1 bit not null, ha iniziato a funzionare per 3 minuti e l'ho interrotta perché stava bloccando tutte le letture al tavolo e sospettavo che ci sarebbe voluto molto tempo per il completamento . È possibile che non ci vorrebbe troppo tempo ma non potrei rischiare troppa indisponibilità. Il rollback stesso ha richiesto 6 minuti.

Hai qualche suggerimento su come posso rendere la colonna non annullabile senza che il completamento richieda potenzialmente ore? Inoltre, esiste un modo per stimare quanto tempo ALTER TABLE ALTER COLUMNrichiederebbe il completamento dell'istruzione che ho iniziato e poi annullato?

Sto usando SQL Server 2017 Web Edition.

Risposte:


12

Invece di modificare la definizione della colonna, è possibile aggiungere un CHECK CONSTRAINTche non consente NULL per quella colonna. La tabella dovrà comunque essere scansionata ma non dovrà modificare ogni singola pagina di dati, quindi dovrebbe essere un'operazione molto più veloce. Purtroppo, durante l'operazione verrà trattenuto un lucchetto Sch-M. Un trucco è provare a ottenere il maggior numero possibile di tabelle nel pool buffer prima di provare ad aggiungere il vincolo. Ciò può ridurre il periodo di tempo in cui il blocco Sch-M viene tenuto.

È quindi possibile rimuovere il vincolo e modificare la definizione della colonna durante la successiva finestra di manutenzione.


Grazie Joe per l'idea. Sono quasi andato con l'aggiunta di un vincolo di controllo ma ho avuto una finestra di manutenzione durante il fine settimana e sono stato in grado di modificare la colonna in modo che non fosse nulla. Non sono sicuro che abbia aiutato, ma per cercare di ottenere i dati della tabella nel pool di buffer, proprio prima di rendere la colonna non annullabile, ho eseguito SELECT c1, count(*) FROM t1 GROUP BY c1che ha richiesto circa 9 minuti. Il completamento della ALTER TABLE ALTER COLUMNdichiarazione vera e propria ha richiesto 25 minuti. Non male.
Ben Amada,

11

Se sei su Enterprise Edition (EE), una strategia migliore potrebbe essere stata quella di aggiungerlo come NOT NULLpredefinito 0o 1(a seconda di quale è il più comune).

Questa è una modifica di soli metadati in EE . Quindi aggiorna quelli che devono essere capovolti. Ciò significa un minor numero di aggiornamenti e non è necessario modificare la nullità della colonna al termine. - Martin Smith


È interessante notare che la scorsa settimana ho notato questa funzione quando ho provato ad aggiungere una colonna di bit non nullable con un valore predefinito a questa stessa grande tabella sul mio computer locale che esegue SQL Developer Edition: la colonna è stata aggiunta istantaneamente e non sono riuscito a capire perché . In seguito mi viene da pensare che l'edizione per sviluppatori include funzionalità EE.
Ben Amada,

-3

Prova a copiare i dati in una nuova tabella, quindi rinominali. Devi occuparti di eventuali vincoli e indici. Questo è ciò che sta facendo il designer di tabelle SSMS quando vuoi riordinare le colonne (ad esempio), ma dovresti controllare lo script per vedere se c'è qualcosa che non sembra giusto.

Durante la copia, l'accesso in lettura alla tabella di origine non è un problema, ma se ci sono scritture che possono essere bloccate o non copiate, a seconda del livello di isolamento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.