it-swarm.it

Come posso sapere PERCHÉ un inserimento su una determinata tabella è lento?

So che un INSERT su una tabella SQL può essere lento per qualsiasi numero di motivi:

  • Esistenza di INSERTI GRILLETTI sul tavolo
  • Molti vincoli forzati che devono essere controllati (di solito chiavi esterne)
  • La pagina si divide nell'indice cluster quando una riga viene inserita al centro della tabella
  • Aggiornamento di tutti gli indici non cluster correlati
  • Blocco da altre attività sul tavolo
  • Scarso IO tempo di risposta in scrittura
  • ... qualcosa che mi mancava?

Come posso sapere qual è il responsabile nel mio caso specifico? Come posso misurare l'impatto delle suddivisioni di pagina rispetto agli aggiornamenti dell'indice non cluster rispetto a tutto il resto?

Ho un proc memorizzato che inserisce circa 10.000 righe alla volta (da una tabella temporanea), che richiede circa 90 secondi per 10k righe. È inaccettabilmente lento, poiché provoca il timeout di altri spid.

Ho esaminato il piano di esecuzione e vedo l'attività INSERISCI INDICE CLUSTERATO e tutti i RICERCHE INDICE delle ricerche FK, ma non mi viene ancora detto con certezza perché ci vuole così tanto tempo. Nessun trigger, ma la tabella ha una manciata di FKeys (che sembrano essere correttamente indicizzati).

Questo è un database SQL 2000.

30
BradC

Alcune cose che puoi guardare ...

Riduci la dimensione del batch da 10000 a qualcosa di più piccolo, come 2000 o 1000 (non hai detto quanto è grande la dimensione della riga).

Prova ad attivare IO Stats per vedere quanto IO stanno prendendo le ricerche FK.

Qual è l'attesa causata da quando si verifica l'inserimento (master.dbo.sysprocesses)?

Cominciamo da qui e vediamo dove andiamo.

10
mrdenny

Brad,

È necessario esaminare le statistiche di attesa per la query. Con SQL2000 è possibile utilizzare la sintassi DBCC SQLPERF ("waitstats") per ottenere tali dettagli.

7
SQLRockstar

Posso dire cosa sto cercando durante l'analisi delle prestazioni di una query. Forse aiuta.

  • analizzare il piano di esecuzione delle query e verificare scansioni dell'indice, scansioni delle tabelle, utilizzo delle funzioni convert_implicit per tipi di dati sql, parallelismo.
  • eseguire la query con SET STATISTICS IO ON e SET STATISTICS TIME ON per visualizzare il tempo di esecuzione e leggere/scrivere io per ogni inserto.
  • controlla il tempo di attesa da sysprocesses per lo spid della sessione.
  • esegui profiler e seleziona modello standard. seleziona quanto segue: Statistiche sulle prestazioni (se ripetute, il tuo piano viene compilato più volte - non va bene), RPC: completato, SQL: batchcompleted e SQL: batchstarting. Aggiungi a loro colonna conteggi righe per vedere esattamente il numero di righe nel batch. Filtra i risultati per vedere solo la tua query.
  • infine raccogliere Aspettativa di vita della pagina contatore dal perfmon di Windows e se è inferiore a 300 (5 min), l'SQL ha memoria insufficiente. Raccogliere anche i contatori del disco: lunghezza della coda del disco, Tempo del disco (unità dei file di dati), Tempo del disco (unità dei file di registro) per vedere se c'è pressione sui dischi.
6
yrushka

Prova a usare:

SET STATISTICS IO ON

e

SET STATISTICS PROFILE ON

STATISTICS IO

Può essere utile per dirti quali tabelle sta eseguendo la maggior quantità di scansioni di tabelle, letture logiche e letture fisiche (io uso questi tre per concentrarmi su quale parte del piano di query ha bisogno della maggior regolazione)

PROFILO STATISTICO

Restituirà principalmente il piano di query in un formato tabulare, quindi puoi guardare le colonne IO e CPU per ciò che costa la maggior parte della query (è la scansione della tabella sulla tua tabella temporanea rispetto al tipo che fa per inserire nella chiave cluster, ecc ...)

5
Andrew Bickerton