Browse Source

Only Prepare DbCommand once (#2801)

* Only Prepare DbCommand once

Moved the `cmd.Prepare()` call from `ReadSingleRow` to `CreateReadCommand` so it's only executed once instead of repeatedly.

* Helps if you commit the right copy of the file
Mark Rendle 8 years ago
parent
commit
4830e2fc3c
1 changed files with 46 additions and 39 deletions
  1. 46 39
      frameworks/CSharp/aspnetcore/Benchmarks/Data/RawDb.cs

+ 46 - 39
frameworks/CSharp/aspnetcore/Benchmarks/Data/RawDb.cs

@@ -28,20 +28,19 @@ namespace Benchmarks.Data
         public async Task<World> LoadSingleQueryRow()
         public async Task<World> LoadSingleQueryRow()
         {
         {
             using (var db = _dbProviderFactory.CreateConnection())
             using (var db = _dbProviderFactory.CreateConnection())
-            using (var cmd = CreateReadCommand(db))
             {
             {
                 db.ConnectionString = _connectionString;
                 db.ConnectionString = _connectionString;
                 await db.OpenAsync();
                 await db.OpenAsync();
 
 
-                return await ReadSingleRow(db, cmd);
+                using (var cmd = CreateReadCommand(db))
+                {
+                    return await ReadSingleRow(db, cmd);
+                }
             }
             }
         }
         }
         
         
         async Task<World> ReadSingleRow(DbConnection connection, DbCommand cmd)
         async Task<World> ReadSingleRow(DbConnection connection, DbCommand cmd)
         {
         {
-            // Prepared statements improve PostgreSQL performance by 10-15%
-            cmd.Prepare();
-
             using (var rdr = await cmd.ExecuteReaderAsync(CommandBehavior.SingleRow))
             using (var rdr = await cmd.ExecuteReaderAsync(CommandBehavior.SingleRow))
             {
             {
                 await rdr.ReadAsync();
                 await rdr.ReadAsync();
@@ -64,6 +63,10 @@ namespace Benchmarks.Data
             id.Value = _random.Next(1, 10001);
             id.Value = _random.Next(1, 10001);
             cmd.Parameters.Add(id);
             cmd.Parameters.Add(id);
 
 
+            // Prepared statements improve PostgreSQL performance by 10-15%
+            // Especially if you only call them once, instead of on every execution :)
+            cmd.Prepare();
+
             return cmd;
             return cmd;
         }
         }
 
 
@@ -72,14 +75,16 @@ namespace Benchmarks.Data
             var result = new World[count];
             var result = new World[count];
 
 
             using (var db = _dbProviderFactory.CreateConnection())
             using (var db = _dbProviderFactory.CreateConnection())
-            using (var cmd = CreateReadCommand(db))
             {
             {
                 db.ConnectionString = _connectionString;
                 db.ConnectionString = _connectionString;
                 await db.OpenAsync();
                 await db.OpenAsync();
-                for (int i = 0; i < count; i++)
+                using (var cmd = CreateReadCommand(db))
                 {
                 {
-                    result[i] = await ReadSingleRow(db, cmd);
-                    cmd.Parameters["@Id"].Value = _random.Next(1, 10001);
+                    for (int i = 0; i < count; i++)
+                    {
+                        result[i] = await ReadSingleRow(db, cmd);
+                        cmd.Parameters["@Id"].Value = _random.Next(1, 10001);
+                    }
                 }
                 }
             }
             }
 
 
@@ -93,43 +98,45 @@ namespace Benchmarks.Data
             var updateCommand = new StringBuilder(count);
             var updateCommand = new StringBuilder(count);
 
 
             using (var db = _dbProviderFactory.CreateConnection())
             using (var db = _dbProviderFactory.CreateConnection())
-            using (var updateCmd = db.CreateCommand())
-            using (var queryCmd = CreateReadCommand(db))
             {
             {
                 db.ConnectionString = _connectionString;
                 db.ConnectionString = _connectionString;
                 await db.OpenAsync();
                 await db.OpenAsync();
 
 
-                for (int i = 0; i < count; i++)
+                using (var updateCmd = db.CreateCommand())
+                using (var queryCmd = CreateReadCommand(db))
                 {
                 {
-                    results[i] = await ReadSingleRow(db, queryCmd);
-                    queryCmd.Parameters["@Id"].Value = _random.Next(1, 10001);
-                }
+                    for (int i = 0; i < count; i++)
+                    {
+                        results[i] = await ReadSingleRow(db, queryCmd);
+                        queryCmd.Parameters["@Id"].Value = _random.Next(1, 10001);
+                    }
 
 
-                // postgres has problems with deadlocks when these aren't sorted
-                Array.Sort<World>(results, (a, b) => a.Id.CompareTo(b.Id));
+                    // postgres has problems with deadlocks when these aren't sorted
+                    Array.Sort<World>(results, (a, b) => a.Id.CompareTo(b.Id));
 
 
-                for(int i = 0; i < count; i++)
-                {
-                    var id = updateCmd.CreateParameter();
-                    id.ParameterName = BatchUpdateString.Strings[i].Id;
-                    id.DbType = DbType.Int32;
-                    updateCmd.Parameters.Add(id);
-
-                    var random = updateCmd.CreateParameter();
-                    random.ParameterName = BatchUpdateString.Strings[i].Random;
-                    id.DbType = DbType.Int32;
-                    updateCmd.Parameters.Add(random);
-
-                    var randomNumber = _random.Next(1, 10001);
-                    id.Value = results[i].Id;
-                    random.Value = randomNumber;
-                    results[i].RandomNumber = randomNumber;
-
-                    updateCommand.Append(BatchUpdateString.Strings[i].UpdateQuery);
-                }
+                    for(int i = 0; i < count; i++)
+                    {
+                        var id = updateCmd.CreateParameter();
+                        id.ParameterName = BatchUpdateString.Strings[i].Id;
+                        id.DbType = DbType.Int32;
+                        updateCmd.Parameters.Add(id);
+
+                        var random = updateCmd.CreateParameter();
+                        random.ParameterName = BatchUpdateString.Strings[i].Random;
+                        id.DbType = DbType.Int32;
+                        updateCmd.Parameters.Add(random);
+
+                        var randomNumber = _random.Next(1, 10001);
+                        id.Value = results[i].Id;
+                        random.Value = randomNumber;
+                        results[i].RandomNumber = randomNumber;
+
+                        updateCommand.Append(BatchUpdateString.Strings[i].UpdateQuery);
+                    }
 
 
-                updateCmd.CommandText = updateCommand.ToString();
-                await updateCmd.ExecuteNonQueryAsync();
+                    updateCmd.CommandText = updateCommand.ToString();
+                    await updateCmd.ExecuteNonQueryAsync();
+                }
             }
             }
 
 
             return results;
             return results;
@@ -169,4 +176,4 @@ namespace Benchmarks.Data
             return result;
             return result;
         }
         }
     }
     }
-}
+}