Question

Je l'ai finalement obtenu mon lot d'insertion au travail et maintenant j'ai jongler avec la taille du lot, mais je ne vois aucune différence de performance entre une valeur de 50 et une valeur de 10000. Cela semble très étrange pour moi, mais je ne sais pas ce qui se passe derrière la scène, il est peut-être un comportement normal.

Je suis d'insérer 160K lignes dans une table et le temps moyen pour mes valeurs testées est de 115 +/- 2 secondes. Sans Batching il faut 210 secondes, donc je suis très satisfait de l'amélioration. La table cible est:

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]

Je lis Que rechercher lors de la création UpdateBatchSize la réponse était de tester simplement un couple de valeurs différentes. Je peux comprendre, mais il ne devrait pas être possible de calculer ou au moins devinestimer une bonne valeur si vous connaissez la conception de la table, la question SQL et les données qui va être inséré?

Y a-t-il des meilleures pratiques là-bas que quelqu'un peut recommander?

Était-ce utile?

La solution

Vous pouvez voir l'effet de batching soit en consultant Profiler SQL ou en appelant SqlConnection.RetrieveStatistics(). Ce que vous devez voir est que chaque lot correspond à à un seul aller-retour à la DB.

En ce qui concerne la façon d'optimiser la taille du lot, une règle de pouce très rugueuse est que la performance a tendance à cesser de s'améliorer avec des tailles de lots ci-dessus 50 - en fait, parfois des lots plus importants peuvent fonctionner plus lentement que les plus petits. Si je suis trop occupé à tester, je commence généralement avec un lot d'environ 20 (à moins que je suis en utilisant le tableau des paramètres évalués, où des lots jusqu'à 500 peuvent être plus rapides que les plus petits). Cependant, le nombre optimal dépend de choses comme la taille totale des inserts (vont-ils tous en forme dans la RAM), à quelle vitesse les disques sont que votre DB journal se trouve sur, si le journal est sur un lecteur / LUN de son propre ( coût énorme perf si ce n'est pas), etc.

La vitesse réalisable est généralement limitée d'abord par le nombre d'allers-retours, puis par taille de transaction, puis connectez la vitesse du disque (en particulier si l'accès séquentiel est possible ou si elle est forcée à cause aléatoire à la concurrence avec d'autres fichiers sur les mêmes broches) , et enfin la RAM. Cependant, tous les facteurs également liés entre eux dans une certaine mesure.

La première étape dans l'amélioration de la perf de vos inserts serait de les faire dans les transactions - peut-être une transaction chaque lot ou deux. Au-delà, les paramètres d'une valeur de table est probablement l'étape suivante, en utilisant une procédure stockée avec INSERT INTO Table SELECT column FROM @TableArgument.

Autres conseils

Bien que le changement UpdateBatchSize contribue dans une certaine mesure, l'approche fondamentale de l'utilisation d'un DataAdapter pour mettre à jour un grand nombre de dossiers va être lente. En effet, en fin de compte, une instruction SQL séparée (insertion, mise à jour ou suppression) sera généré par le DataAdapter pour chaque ligne. UpdateBatchSize ne concerne que le nombre de ces déclarations individuelles sont envoyés dans un lot TSQL lors de l'envoi à SQL Server.

Pour obtenir des améliorations beaucoup plus importantes dans la performance, vous voulez SQLServer insérer / mettre à jour / supprimer plusieurs enregistrements dans une instruction (typiquement en utilisant une REJOIGNEZ de quelque sorte). Tableau des paramètres évalués (comme indiqué par RickNZ) est une façon de le faire. Une autre possibilité est d'utiliser SqlBulkCopy (bien que vous aurez généralement besoin d'utiliser une table de mise en scène pour cela).

Assurez-vous qu'il ya aussi une transaction active, elle améliorera les performances grandement (environ 30x dans mes tests à l'aide MysqlDataAdapter).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top