Domanda

Ho finalmente ottenuto il mio inserto batch per lavoro e ora sono stato a giocherellare con la dimensione della partita, ma non riesco a vedere alcuna differenza in termini di prestazioni tra un valore di 50 e un valore di 10000. Questo sembra molto strano per me, ma non so cosa sta succedendo dietro le quinte, quindi potrebbe essere un comportamento normale.

sto inserendo 160K righe in una tabella e il tempo medio per i miei valori testati è di 115 +/- 2 secondi. Senza il dosaggio ci vuole 210 secondi, quindi sono abbastanza soddisfatto del miglioramento. La tabella di destinazione è:

CREATE TABLE [dbo].[p_DataIdeas](
    [wave] [int] NOT NULL,
    [idnumber] [int] NOT NULL,
    [ideaID] [int] NOT NULL,
    [haveSeen] [bit] NOT NULL CONSTRAINT [DF_p_DataIdeas_haveSeen]  DEFAULT ((0)),
  CONSTRAINT [PK_p_DataIdeas] PRIMARY KEY CLUSTERED 
(
  [wave] ASC,
  [idnumber] ASC,
  [ideaID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON
) ON [PRIMARY]
) ON [PRIMARY]

Che cosa cercare quando si impostano UpdateBatchSize la risposta era di testare semplicemente un paio di valori diversi. Posso capire che, ma non dovrebbe essere possibile calcolare o almeno stimarne un valore buono se si conosce la struttura della tabella, la questione SQL ed i dati che sta per essere inserito?

Ci sono delle migliori pratiche là fuori che qualcuno può raccomandare?

È stato utile?

Soluzione

È possibile vedere l'effetto del dosaggio sia, cercando in SQL Profiler o chiamando SqlConnection.RetrieveStatistics(). Che cosa si dovrebbe vedere è che ognuno corrisponde a un singolo lotto di andata e ritorno al DB.

Per quanto come ottimizzare la dimensione del lotto, una regola empirica-molto approssimativa è che le prestazioni tende a fermarsi migliorare con lotti di sopra di circa 50 - infatti, a volte lotti più grandi possono eseguire più lentamente di quelli piccoli. Se sono troppo occupato per prova, ho in genere inizia con un lotto di circa 20 (a meno che non sto usando da tavolo parametri stimati, dove lotti fino a 500 può essere più veloce di quelli più piccoli). Tuttavia, il numero ottimale dipende cose come la dimensione totale degli inserti (saranno tutti in forma in RAM), quanto velocemente i dischi sono che il registro DB si trova, se il registro si trova su un'unità / LUN della propria ( costo perf grande se non è), ecc.

La velocità raggiungibile è generalmente limitata dapprima dal numero di rotazioni, poi per dimensione transazione, quindi accedere velocità del disco (in particolare se è possibile l'accesso sequenziale o se è costretto a causa casuale concorrenza con altri file sugli stessi mandrini) e, infine, RAM. Tuttavia, tutti i fattori anche collegati tra loro in una certa misura.

Il primo passo per migliorare la perf dei tuoi inserti sarebbe quella di fare loro in transazioni - forse una transazione ogni lotto o due. Oltre a ciò, con valori di tabella parametri è probabilmente il passo successivo, utilizzando una stored procedure con INSERT INTO Table SELECT column FROM @TableArgument.

Altri suggerimenti

Anche se cambiando UpdateBatchSize contribuirà in una certa misura, l'approccio di base di utilizzare un DataAdapter per aggiornare un sacco di dischi sta per essere lento. Questo perché in definitiva, un'istruzione SQL separato (inserimento, aggiornamento o cancellazione) sarà generato dal DataAdapter per ogni riga. UpdateBatchSize riguarda solo quanti di quei singoli dichiarazioni vengono inviati in un unico lotto TSQL quando vengono inviati a SQL Server.

Per ottenere molto più grandi miglioramenti nelle prestazioni, si vuole SQLServer di inserire / aggiornare / cancellare molti record in un unico prospetto (in genere utilizzando un JOIN di qualche tipo). Tabella parametri valutati (come detto da RickNZ) è un modo di fare questo. Un'altra possibilità sta usando SqlBulkCopy (anche se sarà in genere necessario utilizzare una tabella di gestione temporanea per questo).

Assicurarsi che ci sia anche una transazione attiva che migliorerà le prestazioni notevolmente (circa 30x nel mio test utilizzando MySqlDataAdapter).

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