c# - telecharger - Est-il préférable d'exécuter plusieurs commandes SQL avec une seule connexion ou de se reconnecter à chaque fois?




telecharger php (4)

En définitive, il est préférable d’avoir une seule connexion. Vous exécutez peut-être votre point de référence avec une petite quantité de données. Essayez d'augmenter le nombre à 1 000 ou 10 000.

En outre, en fonction de la configuration de votre application, vous pouvez penser que vous utilisez plusieurs connexions, mais que .NET met en pool des connexions pour vous. Vous utilisez donc essentiellement les mêmes connexions.

Voici mon code de test, qui semble suggérer qu'il est préférable de se connecter plusieurs fois plutôt que de se connecter une seule fois.

Est-ce que je fais quelque chose de mal?

int numIts = 100;
Stopwatch sw = new Stopwatch();
sw.Start();
using (SqlConnection connection = new SqlConnection(connectionParameters))
{   
            connection.Open();
    for(int i = 0; i < numIts; i++)
    {
        SqlCommand command = new SqlCommand(sqlCommandName, connection);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue(par1Name, par1Val);
                command.Parameters.AddWithValue(par2Name, par2Val);
        using(SqlDataReader reader = command.ExecuteReader())
        {
        }
    }
}
sw.Stop();
TimeSpan durationOfOneConnectionManyCommands = sw.Elapsed;
Console.WriteLine(durationOfOneConnectionManyCommands);

sw.Reset();

sw.Start();
for(int i = 0; i < numIts; i++)
{
    using (SqlConnection connection = new SqlConnection(connectionParameters))
    {   
                connection.Open();
        SqlCommand command = new SqlCommand(sqlCommandName, connection);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue(par1Name, par1Val);
                command.Parameters.AddWithValue(par2Name, par2Val);
        using(SqlDataReader reader = command.ExecuteReader())
        {
        }
    }                               
}
sw.Stop();
TimeSpan durationOfManyConnections = sw.Elapsed;
Console.WriteLine(durationOfManyConnections);

Sortie:

//output:
//00:00:24.3898218   // only one connection established
//00:00:23.4585797   // many connections established.
//
//output after varying parameters (expected much shorter):
//00:00:03.8995448
//00:00:03.4539567

Mettre à jour:

OK, donc ceux qui ont dit que ce serait plus rapide avec une connexion l’ont. (Bien que la différence soit marginale, le cas échéant.) Voici le code et le résultat révisés:

public void TimingTest()
{
    numIts = 1000;
    commandTxt = "select " + colNames + " from " + tableName;

    OneConnection();
    ManyConnections();
    OneConnection();
}
private void ManyConnections()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    for (int i = 0; i < numIts; i++)
    {
        using (SqlConnection connection = new SqlConnection(connectionParameters))
        {
            connection.Open();
            using (SqlCommand command = connection.CreateCommand())
            {
                command.CommandText = commandTxt;

                using (SqlDataReader reader = command.ExecuteReader())
                {
                }
            }
        }
    }
    sw.Stop();
    TimeSpan durationOfManyConnections = sw.Elapsed;
    Console.WriteLine("many connections: " + durationOfManyConnections);
}
private void OneConnection()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    using (SqlConnection connection = new SqlConnection(connectionParameters))
    {
        connection.Open();
        for (int i = 0; i < numIts; i++)
        {
            using (SqlCommand command = connection.CreateCommand())
            {
                command.CommandText = commandTxt;
                using (SqlDataReader reader = command.ExecuteReader())
                {
                }
            }
        }
    }
    sw.Stop();
    TimeSpan durationOfOneConnectionManyCommands = sw.Elapsed;
    Console.WriteLine("one connection: " + durationOfOneConnectionManyCommands);
}

Sortie:

one connection: 00:00:08.0410024
many connections: 00:00:08.7278090
one connection: 00:00:08.6368853

one connection: 00:00:10.7965324
many connections: 00:00:10.8674326
one connection: 00:00:08.6346272

Mettre à jour:

la différence est plus frappante si j'utilise SQLConnection.ClearAllPools() après chaque fonction:

Sortie:

one connection: 00:00:09.8544728
many connections: 00:00:11.4967753
one connection: 00:00:09.7775865

En général, le regroupement de connexions de .NET devrait en faire une solution de rechange, car il permet de recycler les connexions pour vous. Mais ma pratique est d’utiliser une seule connexion pour un ensemble de transactions qui, je le sais, se dérouleront ensemble. Je pense que votre minutage est une indication du pool de connexion qui fait son travail et de simples variations dans les exécutions.


Par défaut, SqlConnection utilisera le regroupement de connexions. Par conséquent, votre code n'ouvre probablement pas beaucoup de connexions dans les deux cas.

Vous pouvez contrôler si SqlConnection utilisera le pool en activant ou en désactivant le pool dans la chaîne de connexion. Selon la base de données pour laquelle votre chaîne de connexion est utilisée, la syntaxe varie.

Voir here pour quelques informations si vous utilisez MSSQLServer. Essayez de définir Pooling = false dans la chaîne de connexion et voyez si cela fait une différence.


SqlClient mettra en commun vos connexions. Dans votre premier cas avec un ouvert, il s’agira d’ouvrir la connexion. Toute autre exécution utilisera la connexion en pool. Si vous inversez votre ordre et faites "beaucoup de connexions" en premier, je vous attendrais à voir le résultat inverse.





sqlconnection