Maison  >  Article  >  développement back-end  >  Pourquoi la base de données/sql dans Go est-elle plus lente que la requête directe de base de données et comment puis-je y remédier ?

Pourquoi la base de données/sql dans Go est-elle plus lente que la requête directe de base de données et comment puis-je y remédier ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-17 13:57:02662parcourir

Why is database/sql in Go Slower Than Direct Database Querying, and How Can I Fix It?

Enquête sur la disparité des performances des requêtes : base de données/sql vs requête directe

Les requêtes exécutées à l'aide du package base de données/sql Go sont nettement plus lentes que les requêtes équivalentes exécutées directement sur la base de données . Pour remédier à cette disparité, il est essentiel d'approfondir les mécanismes sous-jacents.

Gestion des connexions dans base de données/sql

L'objet sql.DB représente un pool de connexions, pas une seule connexion. Lorsque sql.Open est appelé, il initialise le pool mais ne peut établir aucune connexion. Ce n'est que lorsqu'une requête est demandée qu'une nouvelle connexion est créée.

Impact sur le timing des requêtes

Dans l'extrait de code fourni, la première requête rencontre un problème de performances car elle déclenche la création d'un nouveau connexion à la base de données. La deuxième requête présente également un écart de performances dû au manque de réutilisation des connexions. Chaque requête établit une nouvelle connexion au lieu d'utiliser une connexion inactive existante du pool.

Libération des connexions vers le pool

Pour résoudre ce problème, il est crucial de libérer les connexions vers le pool. après chaque requête. Ceci peut être réalisé en conservant la première valeur de retour de db.Query, qui représente les résultats de la requête, et en invoquant .Close() dessus.

Établir une connexion inactive

Pour commencer avec un connexion disponible dans le pool, appelez Ping sur l'objet sql.DB après initialisation. Cela forcera la création d'une connexion initiale.

Instructions préparées et paramètres de position

Les instructions préparées sont utilisées lorsque les requêtes contiennent des arguments. Le protocole Postgres active les paramètres au lieu de l'insertion directe de valeurs dans la chaîne de requête. Ce paramétrage séparé permet une gestion plus efficace des requêtes.

Exemple de code

L'extrait de code suivant illustre comment gérer correctement les connexions et réutiliser les instructions préparées :

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/lib/pq"
    "time"
)

func main() {
    // Initialize database connection with initial idle connection
    db, err := sql.Open("postgres", "postgres:///?sslmode=disable")
    if err != nil {
        panic(err)
    }
    if err := db.Ping(); err != nil {
        panic(err)
    }

    for i := 0; i < 5; i++ {
        // Prepare query
        query := "select 1 where true"
        stmt, err := db.Prepare(query)
        if err != nil {
            panic(err)
        }

        // Execute and time query
        firstQueryStart := time.Now()
        rows, err := stmt.Query()
        firstQueryEnd := time.Now()
        if err != nil {
            panic(err)
        }

        // Release connection back to pool
        rows.Close()

        fmt.Println(fmt.Sprintf("query #%d took %s", i, firstQueryEnd.Sub(firstQueryStart).String()))
    }
}

Par en mettant en œuvre ces optimisations, l'écart de performances des requêtes peut être considérablement réduit, offrant des temps d'exécution comparables aux requêtes directes.

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!

Déclaration:
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