L'éditeur PHP Youzi vous présentera aujourd'hui une technique importante : comment réduire la consommation de mémoire lors de l'exécution de transactions volumineuses. La consommation de mémoire peut devenir un problème sérieux lors du traitement de grandes quantités de données ou de l'exécution d'opérations complexes. Pour résoudre ce problème, nous devons prendre des mesures d'optimisation pour améliorer l'efficacité et les performances du code. Cet article vous présentera en détail certaines méthodes et techniques pour réduire la consommation de mémoire et vous aidera à utiliser les ressources mémoire plus efficacement lors du traitement de transactions volumineuses.
J'ai suivi les exemples sur Internet et utilisé les paramètres sqlite suivants pour améliorer la vitesse des requêtes d'insertion :
pragma journal_mode = off; pragma synchronous = 0; pragma cache_size = 1000000; pragma locking_mode = exclusive; pragma temp_store = memory;
Voici mon code :
tx, err := db.begin() if err != nil { log.fatal(err) } pr, err := tx.prepare("insert into table (p1, p2, p3, p4, p5) values (?, ?, ?, ?, ?)") if err != nil { log.fatal(err) } defer pr.close() for i := 0; i < maxi; i++ { for j := 0; j < maxj; j++ { ... _, err = pr.exec(param1, param2, param3, param4, param5) if err != nil { log.fatal(err) } } } err = tx.commit() if err != nil { log.fatal(err) }
Maintenant, la requête s'exécute rapidement mais consomme trop de RAM. Étant donné que les données sont stockées dans la RAM, elles ne sont enregistrées dans le fichier de base de données qu'à la fin de l'exécution.
Je pense qu'il est possible de sauvegarder périodiquement les données dans un fichier de base de données, ce qui augmentera légèrement le temps d'exécution mais réduira la consommation de mémoire. A chaque changement de "i", la transaction démarre et lorsque tous les "j" sont complétés, la transaction se termine :
for i := 0; i < maxI; i++ { tx, err := db.Begin() if err != nil { log.Fatal(err) } pr, err := tx.Prepare("INSERT INTO Table (p1, p2, p3, p4, p5) VALUES (?, ?, ?, ?, ?)") if err != nil { log.Fatal(err) } defer pr.Close() for j := 0; j < maxJ; j++ { ... _, err = pr.Exec(param1, param2, param3, param4, param5) if err != nil { log.Fatal(err) } } err = tx.Commit() if err != nil { log.Fatal(err) } }
Je pense que maintenant les données devraient être écrites dans le fichier en morceaux et qu'il ne devrait y avoir qu'un seul morceau de données dans la RAM.
Mais lors de l'exécution, les données ne sont pas enregistrées dans le fichier et le bélier continue de se remplir. Autrement dit, il n'y a aucune différence dans l'exécution des première et deuxième options de code.
Je pense que lorsque le "commit" de la transaction est appelé, les données doivent être enregistrées dans le fichier et le RAM doit être effacé. S'il vous plaît, dites-moi ce que je fais de mal.
PRAGMAcache_size
Le paramètre est le nombre de pages (généralement 4k octets par page).
PRAGMA cache_size = 1000000;
Un maximum de 4 Go de RAM sera alloué au cache des pages.
Le cache de pages est alloué en cas de besoin, jusqu'à une taille maximale, mais n'est libéré qu'une fois la connexion fermée.
Puisque vous insérez un grand nombre de lignes, elles se retrouveront sur des pages différentes, vous finirez donc par conserver dans le cache toutes les pages qui ont été écrites sur le disque jusqu'à ce que le cache soit rempli.
Si vous souhaitez réduire la consommation de mémoire, réduisez simplement la valeur à quelque chose comme 1000 (équivalent à 4 Mo), ou supprimez-la simplement. Le cache par défaut est de 2 Mo, ce qui est suffisant si vous insérez simplement des lignes.
Notez également que les données sont écrites sur le disque lorsque vous appelez COMMIT (ou même avant la validation s'il n'y a pas suffisamment de cache). Mais SQLite conserve une copie dans le cache au cas où vous en auriez besoin plus tard pour éviter de la relire à partir du disque.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!