SQLite/C# Regroupement de connexions et de l'Instruction Préparée Confusion
J'ai passé quelque temps à la lecture de différents les meilleures pratiques pour les bases de données SQLite en particulier. Lors de la lecture, j'ai trouvé que je faisais beaucoup de choses que je ne devrais pas être en train de faire et lorsque vous tentez de résoudre ces problèmes, je suis devenu confus quand penser à quelques-uns des détails les plus précis de l'utilisation de SQLite avec son ADO de mise en œuvre.
Ma confusion vient précisément de déclarations préparées à l'avance et le regroupement de connexion.
Lors de la lecture de http://msdn.microsoft.com/en-us/library/ms971481.aspx j'ai trouvé que les connexions ne doit être ouvert que pour une transaction. Une fois que la transaction est terminée, la connexion devrait être fermé. Je n'ai pas bien saisi pourquoi c'est le cas, mais je travaille hors de l'hypothèse que l'auteur(s) mieux connaître puis I. je comprends que, quand une connexion est fermée, cela ne signifie pas qu'il a été effectivement fermé. Cela signifie simplement qu'il a été mis de nouveau dans la piscine.
Maintenant pour améliorer mes requêtes et insère j'ai lu sur l'utilisation des requêtes préparées. Dans SQLite, faire des déclarations préparées vraiment améliorer les performances? et http://petesbloggerama.blogspot.com/2007/02/sqlite-adonet-prepared-statements.html les deux semblaient indiquer que lors de l'exécution d'une requête qui sera fait à de multiples reprises des déclarations préparées sont la voie à suivre. J'ai aussi lu qu'une instruction préparée est spécifique à une connexion et une fois que la connexion est fermée à l'instruction préparée est perdu.
Ma confusion est présente. Si je suis d'ouverture et de fermeture de ma connexion (qui peut ou peut ne pas signifier la connexion est fermée en raison du pool de threads) puis combien suis-je vraiment obtenir à partir d'une requête préparée? Je peux comprendre que, si j'ai 1000 objets, j'ai besoin d'enregistrer en une seule transaction pour l'instruction préparée peut aider beaucoup. Cependant, je ne crois pas que je voudrais voir un avantage de l'enregistrement d'un unique objet dans une transaction, car une fois que je ferme la connexion à la déclaration qui a été généré à partir de la première de l'objet est maintenant perdu. Est-ce une vraie déclaration?
Ma confusion est renforcée par le fait que je crois une instruction préparée est liée à la portée de mon SQLiteCommand objet.
Si je crée un SQLiteCommand qui représente une requête que je vais être en cours d'exécution, souvent, dois-je les garder que SQLiteCommand en mémoire pour l'instruction préparée pour rester actif?
Si je crée un nouveau SQLiteCommand avec la même instruction SQLite est-il reconnu que la nouvelle SQLiteCommand est le même que le précédent et a donc préparé un énoncé qui peut être utilisé?
Si je garde un SQLiteCommand dans la mémoire et de modifier ses paramètres de connexion et comme je l'ouvrir et de fermer la connexion pour les différentes opérations je suis essentiellement en gardant une déclaration préparée vivant entre les différentes connexions?
Je suis le plus probable de penser les choses à ce point, mais j'espère que vous pourrez m'aider à mieux comprendre comment ces choses interagissent afin que je puisse obtenir le plus d'avantages de leur.
- Je ne suis pas très versé dans SQLite, mais aussi pourquoi il faut fermer les connexions dès que possible, vous est venu assez proche pour y répondre vous-même: La physique sous-jacente, la connexion n'est pas fermée, il vous suffit de retourner la connexion à la piscine. L'implication est qu'il peut être utilisé par d'autres threads. Clairement, si vous vous accrochez à une connexion, mais n'en utilisent pas, ce qui limitera le maximum d'utilisation possible. (Tout aussi clairement: si vous êtes dans un seul thread contexte, le regroupement de connexions ne fait pas beaucoup de sens, si elle est unlikley de vous blesser beaucoup.)
Vous devez vous connecter pour publier un commentaire.
Il aide à se rappeler que le regroupement de connexions et préparé (compilé) les instructions sont simplement des outils qui ont leurs limites, et aucune approche ne peut être aussi adapté à toutes les situations possibles. Avec cela à l'esprit, n'oublions pas quand on pourrait vouloir utiliser le regroupement de connexion et de déclarations préparées à l'avance.
Raisons possibles pour Utiliser le Regroupement de Connexion
Le regroupement de connexion est utile lorsque les connexions sont chers, par exemple:
Raisons possibles pour Utiliser les requêtes Préparées
Préparées sont simplement destinées à améliorer les performances de ré-utilisable requêtes en coupant l'analyse.
SQLite: Quel est le Meilleur Choix?
La réponse dépend des exigences de votre application. Personnellement, je ne suis pas sûr si SQLite pool de connexion est forcément un bon choix. Si votre demande est monothread, il pourrait être préférable d'utiliser une seule connexion permanente à l'SQLite DB, ce qui pourrait être beaucoup plus rapide que la mise en commun et vous permettrait d'utiliser les requêtes préparées trop. Ceci est différent de SQL Server où le regroupement de connexion est très raisonnable par défaut.
Si la performance est importante, vous devriez certainement profil de l'application pour voir si la connexion SQLite mise en commun est bénéfique pour votre scénario.
Questions Spécifiques
La plupart des réponses sont liées à l'
System.Data.SQLite
fournisseur de source.En général, vous devez traiter une connexion en sortant de la piscine en tant que nouveau, c'est à dire que vous ne devriez pas attendre pour obtenir de bénéficier de la consolidés établis précédemment. La déclaration sera "re-préparé" à moins que vous garder à la fois le commandement et la connexion.
Cette affirmation est vraie.
Oui, vous avez besoin de le garder.
SQLiteCommand
contient une référence à la déclaration préparée.Je ne pense pas que c'est pris en charge.
Si vous modifiez le
SQLiteCommand
's de connexion, la déclaration sera "re-préparé".Je n'ai pas compris exactement ce qui est le cœur du problème, mais si le problème est de savoir comment insérer bulk insert dans une transaction en si peu de temps.
Ici est une classe d'aide, j'ai trouvé plus tôt qui pourrait vous aider:
SQLiteBulkInsertHelper.cs
Vous pouvez l'utiliser comme ceci:
L'essayer si vous le voyez comme une solution à votre problème.