Performances en PDO / PHP / MySQL: transaction versus exécution directe
-
06-07-2019 - |
Question
Je boucle plusieurs valeurs (1 à 100 par exemple) et exécute une instruction préparée à l'intérieur de la boucle.
Existe-t-il un avantage à utiliser une transaction - une validation après la fin de la boucle - par rapport à une exécution directe dans la boucle?
Les valeurs ne dépendant pas les unes des autres, une transaction n'est donc pas nécessaire de ce point de vue.
La solution
Si vos requêtes sont des insertions, la page 7.2.19 . La rapidité des instructions INSERT du manuel MySQL fournit deux informations intéressantes, selon que vous utilisez ou non un moteur transactionnel:
Si vous utilisez un moteur non transactionnel:
Pour accélérer les opérations INSERT qui sont effectué avec plusieurs déclarations pour tables non transactionnelles, verrouillez votre tables.
Cela améliore les performances car le le tampon d'index est vidé sur le disque uniquement une fois, après que toutes les instructions INSERT ont terminé. Normalement, il y aurait aussi beaucoup de tampons d'indexation comme il y a INSERT déclarations. Verrouillage explicite les déclarations ne sont pas nécessaires si vous le pouvez insérer toutes les lignes avec un seul INSERT.
Et avec un moteur transactionnel:
Pour obtenir des insertions plus rapides pour tables transactionnelles, vous devez utiliser START TRANSACTION et COMMIT à la place des tables de verrouillage.
Donc, je suppose que l'utilisation de transactions pourrait être une bonne idée - mais je suppose que cela pourrait dépendre de la charge de votre serveur, et de savoir s'il existe plusieurs utilisations utilisant la même table au même moment, et tout ça ...
Il y a plus d'informations sur la page vers laquelle je me suis connecté, alors n'hésitez pas à la lire; -)
Et si vous suivez les mises à jour des déclarations :
Un autre moyen d’obtenir des mises à jour rapides consiste à retarder les mises à jour et ensuite faire de nombreuses mises à jour dans une rangée plus tard. Effectuer plusieurs mises à jour ensemble est beaucoup plus rapide que faire un à la fois si vous verrouillez la table.
Donc, je suppose que la même chose peut être dite que pour les inserts.
BTW: pour être sûr, vous pouvez essayer les deux solutions en les comparant avec microtime
, du côté de PHP, par exemple; -)
Autres conseils
Pour un temps plus rapide, vous pouvez effectuer toutes les insertions en une seule prise ou les regrouper, peut-être 5 ou 10 à la fois, comme si une insertion échouait à la totalité du lot.
http://www.desilva.biz/mysql/insert.html
Une transaction vous ralentira. Si vous n'en avez pas besoin, ne l'utilisez pas.
Une instruction préparée serait un bon choix, même si vous utilisiez des insertions par lots, car vous n'avez pas à construire continuellement la requête.
J'ai été confronté à la même question lorsque j'ai dû implémenter une importation de données au format CSV (éventuellement assez long) (je sais que vous pouvez utiliser le LOAD DATA INFILE pour cela, mais je devais appliquer un traitement sur mes champs avant l'insertion).
J'ai donc fait une expérience avec des transactions et un fichier contenant environ 15 000 lignes. Le résultat est que si j'insère tous les enregistrements dans une transaction unique, cela ne prend que quelques secondes et le cpu est lié. Si je n'utilise pas du tout de transaction, cela prend plusieurs minutes et c'est IO borné. En validant toutes les N lignes, j'ai obtenu des résultats intermédiaires.