2011-08-26 6 views
0

Je surveille un dossier pour les fichiers Jpg et j'ai besoin de traiter les fichiers entrants. Je décode le nom de fichier pour obtenir toutes les informations que je veux et les insère dans une table, puis déplace le fichier vers un autre dossier.Insérer des enregistrements plusieurs fois plus rapidement

Le nom de fichier contient déjà toutes les informations que je souhaite. Par exemple.

2011--8-27_13:20:45_MyLocation_User1.jpg. 

Maintenant, je suis en utilisant une déclaration Insert

Private Function InsertToDB(ByVal SourceFile As String, ByVal Date_Time As DateTime, ByVal Loc As String, ByVal User As String) As Boolean 

    Dim conn As SqlConnection = New SqlConnection(My.Settings.ConString) 
    Dim sSQL As String = "INSERT INTO StageTbl ...." 
    Dim cmd As SqlComman 
    cmd = New SqlCommand(sSQL, conn) 

    ....Parameters Set ... 

     conn.Open() 
     cmd.ExecuteNonQuery() 
     conn.Close() 
     conn = Nothing 
     cmd = Nothing 
    End Function 

La fonction sera appelée pour chaque fichier trouvé.

Est-ce le moyen le plus efficace? On dirait que c'est très lent. J'ai besoin de traiter environ 20 ~ 50 fichiers/sec. Probablement une procédure stockée?

Je dois faire ceci aussi vite que possible. Je suppose que l'insertion en vrac ne s'applique pas ici.

Aidez-nous s'il vous plaît.

Répondre

1

L'insertion en vrac pourrait être applicable ici - avez-vous besoin qu'ils soient dans la DB instantanément, ou pourriez-vous simplement accumuler les enregistrements en mémoire, puis les insérer dans la base de données par lots?

Etes-vous également multi-thread - sinon votre processus de bout en bout pourrait être retardé. Une autre solution consisterait à utiliser des files d'attente de messages - placer un message dans la file d'attente pour chaque fichier, puis avoir un processus (sur un thread différent) qui lit continuellement la file d'attente et l'ajoute à la base de données.

1

Il y a plusieurs choses que vous pouvez faire pour optimiser la vitesse de ce processus:

  • Ne pas ouvrir et fermer la connexion pour chaque insertion. Cela seul donnera une amélioration (très) significative des performances (sauf si vous utilisiez déjà le pool de connexion).
  • Vous pouvez améliorer les performances si vous désactivez la validation automatique et exécutez des insertions dans des blocs, en validant la transaction après chaque ligne N (100-1000 lignes est un bon nombre à essayer pour un démarrage).
  • Certains systèmes DB fournissent une syntaxe permettant l'insertion de plusieurs lignes dans une même requête. SQL Server n'est pas mais vous pouvez être intéressé par cela: http://blog.sqlauthority.com/2007/06/08/sql-server-insert-multiple-records-using-one-insert-statement-use-of-union-all/
  • Si plusieurs utilisateurs/processus accèdent à cette table, l'accès peut être lent en fonction de votre niveau d'isolation de transaction. Dans votre cas (20-50 insertions/sec) cela ne devrait pas faire une grande différence. Je ne recommande pas de modifier cela, sauf si vous comprenez bien ce que vous faites: http://en.wikipedia.org/wiki/Isolation_%28database_systems%29 et http://technet.microsoft.com/es-es/library/ms173763.aspx.
  • Je ne pense pas qu'une procédure stockée fournira nécessairement un gros gain de performance. Vous êtes seulement en train d'analyser/planifier l'insertion 20 à 50 fois par seconde. Utilisez une procédure stockée uniquement si elle correspond bien à votre modèle de développement. Si toutes vos autres requêtes sont dans le code, vous pouvez l'éviter.
  • Assurez-vous que votre goulot d'étranglement est la base de données (c'est-à-dire que le déplacement des fichiers ne prend pas beaucoup de temps), mais puisque le système d'exploitation devrait être bon, vérifiez les points ci-dessus. Si vous trouvez que déplacer des fichiers est votre goulot d'étranglement, retarder ou déplacer des fichiers en arrière-plan (un autre thread) peut aider dans une certaine mesure.
Questions connexes