Domanda

Ho creato una tabella nel mio database SQL Server 2005 e l'ho popolata con valori di riepilogo e calcolati. Lo scopo è quello di evitare estesi join e raggruppamenti su ogni chiamata al database. Vorrei che questa tabella si aggiornasse ogni ora, ma non sono sicuro del modo migliore per farlo mentre il sito Web è sotto carico. Se elimino tutti i record e ripopolo la tabella in una transazione, ciò risolverà il problema o ci saranno deadlock e altri problemi in agguato?

È stato utile?

Soluzione

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

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

Probabilmente si tratta del tempo più breve che puoi far attendere agli utenti che i nuovi dati vengano aggiornati e senza interromperli nel mezzo di una lettura. (Ci sono molti problemi associati a NOLOCK che lo rendono un'alternativa meno desiderabile, anche se, ammettiamolo, è facile da programmare.) Per brevità / chiarezza ho tralasciato la gestione degli errori, ecc., E dovrei anche sottolineare che se usi script per sincronizzare i tuoi database, assicurarti di nominare vincoli, indici ecc. uguali su entrambe le tabelle, altrimenti non sarai sincronizzato per metà del tempo. Alla fine della procedura puoi TRUNCARE la nuova tabella fake.MySummary, ma se hai lo spazio, mi piace lasciare lì i dati in modo da poterli sempre confrontare con la versione precedente.

Prima di SQL Server 2005 ho usato sp_rename all'interno della transazione per ottenere esattamente la stessa cosa, tuttavia da quando lo faccio in un lavoro, sono stato contento di passare agli schemi, perché quando l'ho fatto, l'avviso non soppressibile da sp_rename ha smesso di compilare i log della cronologia di SQL Server Agent.

Altri suggerimenti

Puoi anche creare una vista indicizzata a seconda di quanto sia pesante il tuo carico questa potrebbe essere una buona scelta

Dipende dalle relazioni nel database e dalle query eseguite su di esso.

Se si tratta di una tabella di riepilogo in grado di tollerare dati non aggiornati, è possibile popolarli utilizzando query che eseguono i propri SELECT senza blocchi utilizzando il suggerimento di join NOLOCK. NOTA : l'uso del suggerimento NOLOCK dovrebbe essere fatto solo quando si è sicuri delle conseguenze.

Spesso esiste la possibilità di risintonizzare gli indici, per ridurre il caricamento.

Ho deciso di creare i dati in una variabile di tabella @temp. Quindi copierò gli ID di rollup nella tabella temporanea in cui corrispondono. Infine, aggiungerò, aggiornerò e rimuoverò le righe nella tabella di rollup in base alla tabella @temp.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top