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

Prestazioni di diversi approcci ai dati basati sul tempo

Da un lato, è positivo che tu abbia aperto una nuova domanda. Ma d'altra parte, estraendo una query e chiedendo se funziona più velocemente, perde il contesto della domanda precedente, la nuova domanda è troppo isolata. Come sicuramente saprai, l'amministrazione di un database, la gestione delle risorse (memoria/cache, disco, cicli della CPU), la gestione del codice (buono o scadente) che utilizza tali risorse, fanno tutti parte dell'intero quadro. La performance è un gioco di trading, niente è gratuito.

  1. Il problema principale che ho riscontrato è stata la duplicazione della colonna EndDate, che è facilmente ricavabile. Colonne duplicate equivale ad Aggiorna anomalie. Smirkingman ha fornito l'esempio classico:alcune query otterranno un risultato e altre query l'altro. Questo semplicemente non è accettabile per le grandi organizzazioni; o nelle banche (almeno nei paesi sviluppati) dove i dati sono controllati e protetti. Hai infranto una regola di normalizzazione di base e ci sono sanzioni da pagare.

    • Aggiorna Anomail; due versioni (già dettagliate). Gli auditor potrebbero non superare il sistema.

    • Dimensioni della tabella
      In qualsiasi tabella di grandi dimensioni è un problema, specialmente nelle serie temporali o nei dati temporali, dove il numero di colonne è piccolo e il numero di righe è enorme. Quindi, qualcuno dirà, lo spazio su disco è economico. Sì, anche le malattie sessualmente trasmissibili. Ciò che conta è a cosa serve e quanto bene se ne prende cura.

      • Lo spazio su disco
        Può essere economico su un PC, ma su un server di produzione non lo è. Fondamentalmente hai aggiunto il 62% alla dimensione della riga (13 più 8 equivale a 21) e quindi la dimensione della tabella. Presso la banca a cui sono attualmente assegnato, ogni dipartimento che possiede i dati viene addebitato come segue, l'archiviazione basata su SAN è tutto ciò che c'è. Le cifre sono per GB al mese (questa non è una banca australiana di fascia alta):

        $ 1,05 per RAID5 senza mirroring per risincronizzarsi.)

        $ 2,10 per RAID5 con mirroring
        Nella SAN, cioè.

        $ 4,40 per RAID1+0
        Minimo per dati di produzione, backup dei registri delle transazioni e dump notturni del database.

        $ 9,80 per RAID1+0 replicato
        Su un layout SAN identico in un altro sito a prova di bomba. Taglio della produzione in pochi minuti; quasi zero perdite di transazione.

      • Memoria/Cache
        Ok, Oracle non ce l'ha ma i db bancari seri hanno cache e sono gestiti. Data una dimensione della cache specifica, solo il 62% delle righe rientrerà nella stessa dimensione della cache.

      • I/O logici e fisici
        Il che significa il 50% in più di I/O per leggere la tabella; sia lo streaming nella cache che le letture del disco.

  2. Pertanto, se la query funziona meglio o peggio isolatamente, è una questione accademica. Nel contesto di quanto sopra, la tabella è lento e ha prestazioni peggiori del 62%, sempre, a ogni accesso. E sta colpendo ogni altro utente sul server. Alla maggior parte dei DBA non importerà (di certo non lo farei) se il modulo di sottoquery funziona a metà della velocità, perché il loro bonus è legato all'accettazione dell'audit, non solo alle prestazioni del codice.

    • Inoltre, c'è l'ulteriore vantaggio di non dover mai rivedere il codice e correggere le transazioni a causa delle anomalie di aggiornamento.

    • E le transazioni hanno meno punti da aggiornare, quindi sono più piccole; meno blocchi di blocco, ecc.

  3. D'accordo, quella discussione nei commenti è difficile. Nella mia risposta, ho dettagliato e spiegato due sottoquery. C'è stato un malinteso:stavi parlando di questa sottoquery (nella clausola WHERE, una sottoquery di tabella ) e stavo parlando dell'altra sottoquery (nell'elenco delle colonne, una sottoquery scalare ) quando ho detto che si comporta altrettanto velocemente o più velocemente. Ora che è stato chiarito, non posso dire che la prima query sopra (sottoquery nella clausola WHERE, una tabella) funzionerà alla stessa velocità della seconda query (con la colonna duplicata); il primo deve eseguire 3 scansioni, mentre il secondo esegue solo 2 scansioni. (Oserei dire che la seconda scansione della tabella sarà però.)

    Il punto è che, oltre al problema dell'isolamento, non è un confronto equo, ho fatto il commento sulle sottoquery scalari. Non suggerirei che una query a 3 scansioni sia veloce o più veloce di una query a 2 scansioni.

    L'affermazione che ho fatto sulla sottoquery della tabella a 3 scansioni (che cito qui) deve essere presa nel contesto completo (o quel post in toto o quanto sopra). Non mi sto tirando indietro.

    Passo metà della mia vita a rimuovere alternative illegali come colonne duplicate, che si basano sulla questione delle prestazioni, con i creatori che cantano il mantra che il tavolo è lento, quindi si sono "denormalizzati per le prestazioni". Il risultato, prevedibile prima di iniziare, è un tavolo grande la metà, che ha prestazioni due volte più veloci complessivamente . The Times Series è la domanda più comune qui (il link rimanda a un'altra domanda; quale rimanda a un'altra), ma immagina il problema in un database bancario:daily OpeningExposure e ClosingExposure per Security per Holding perUnitTrust perPortfolio .

  4. Ma permettetemi di rispondere a una domanda che non è stata posta. Questo tipo di interazione è normale, non raro quando si lavora con i team di sviluppo interni; si presenta almeno una volta al mese. Uno sviluppatore a rischio di arresto anomalo ha già scritto e testato il suo codice, utilizzando una tabella con una colonna duplicata, vola e ora è in stallo perché non lo inserirò nel db.

    No, lo testerò nel contesto dell'intero sistema e:

    • la metà delle volte, la tabella viene inserita senza la colonna EndDate perché non c'è niente di grave su una query di mezzo secondo che ora viene eseguita in un secondo.

    • L'altra metà delle volte, le prestazioni di [table subquery] non sono accettabili, quindi implemento un indicatore booleano (bit) per identificare IsCurrent . È molto meglio di una colonna duplicata e fornisce 2 velocità di scansione.

    • Non in un milione di anni mi farai duplicare una colonna; aggiungendo il 62% alla dimensione del tavolo; rallentando la tabella nel contesto multiutente completo del 62%; e rischiare di fallire un audit. E non sono un dipendente, non ricevo un bonus.

    Ora varrebbe la pena testarlo:query con una colonna duplicata rispetto a query con un IsCurrent indicatore, nel contesto completo dell'uso complessivo delle risorse.

  5. Smirkingman ha sollevato un buon punto. E lo ribadirò chiaramente, in modo che non venga frammentato e quindi l'uno o l'altro frammento venga attaccato. Per favore, non interromperlo:

    Un database relazionale,
    Normalizzato da un esperto modellatore relazionale, in una vera quinta forma normale

    (nessuna anomalia di aggiornamento; nessuna colonna duplicata),
    con piena conformità relazionale
    (IDEF1X, in particolare per quanto riguarda la minimizzazione di Id Chiavi primarie; e quindi non paralizzare la potenza del motore relazionale)
    comporterà più tabelle più piccole, un database più piccolo,
    con meno indici,
    che richiedono meno join

    (esatto, più tabelle ma meno join),
    e supererà qualsiasi cosa che infranga una di queste regole
    sullo stesso hardware e impresa piattaforma db

    (esclude freeware, MS, Oracle; ma non lasciare che questo ti fermi),
    nel contesto completo della produzione OLTP usa
    di almeno un ordine di grandezza,
    e sarà molto più facile da usare
    e da cambiare

    (mai bisogno di "refactoring").

    L'ho fatto almeno 80 volte. Due ordini di grandezza non sono rari, se lo faccio io stesso, piuttosto che fornire la struttura a qualcun altro per farlo.

Né io, né le persone con cui lavoro o che mi pagano, mi interessa cosa farà una domanda isolatamente.