Maison > développement back-end > Golang > le corps du texte

Réduisez la consommation de mémoire lors de l'exécution de transactions volumineuses

WBOY
Libérer: 2024-02-10 23:06:08
avant
513 Les gens l'ont consulté

Réduisez la consommation de mémoire lors de lexécution de transactions volumineuses

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.

Contenu de la question

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;
Copier après la connexion

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)
}
Copier après la connexion

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)
    }
}
Copier après la connexion

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.

Solution

PRAGMAcache_sizeLe 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!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal