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

Qual è il modo migliore per aggiornare una tabella di rollup sotto carico?

Il modo in cui l'ho fatto in alcuni progetti è utilizzare due copie della tabella in schemi diversi. Quindi qualcosa come:

CREATE SCHEMA fake WITH AUTHORIZATION dbo;
CREATE SCHEMA standby WITH AUTHORIZATION dbo;
GO

CREATE TABLE dbo.mySummary(<...columns...>);

CREATE TABLE fake.mySummary(<...columns...>);
GO

Ora crea una procedura memorizzata che tronca e ripopola la tabella falsa, quindi in una transazione sposta gli oggetti tra gli schemi.

CREATE PROCEDURE dbo.SwapInSummary
AS
BEGIN
    SET NOCOUNT ON;

    TRUNCATE TABLE fake.mySummary;

    INSERT fake.mySummary(<...columns...>)
        SELECT <expensive query>;

    BEGIN TRANSACTION;
        ALTER SCHEMA standby TRANSFER dbo.mySummary;
        ALTER SCHEMA dbo     TRANSFER fake.mySummary;
        ALTER SCHEMA fake    TRANSFER standby.mySummary;
    COMMIT TRANSACTION;
END
GO

Questo è probabilmente il periodo di tempo più breve che puoi far attendere agli utenti per l'aggiornamento dei nuovi dati e senza interromperli nel mezzo di una lettura. (Ci sono molti problemi associati a NOLOCK che lo rendono un'alternativa meno desiderabile, anche se è vero che è facile da programmare.) Per brevità/chiarezza ho omesso la gestione degli errori ecc., E dovrei anche sottolineare che se usi script per sincronizzare i tuoi database, assicurati di nominare vincoli, indici ecc. lo stesso su entrambe le tabelle, altrimenti sarai fuori sincronia per metà del tempo. Al termine della procedura puoi TRUNCARE la nuova tabella fake.MySummary, ma se hai lo spazio, mi piace lasciare i dati lì così posso sempre confrontare con la versione precedente.

Prima di SQL Server 2005 usavo sp_rename all'interno della transazione per ottenere esattamente la stessa cosa, tuttavia poiché lo faccio in un lavoro, ero felice di passare agli schemi, perché quando l'ho fatto, l'avviso non sopprimibile da sp_rename ha smesso di riempirsi nei registri della cronologia di SQL Server Agent.