SqlDataReader .ReadAsync() vs .Read()

SqlDataReader .ReadAsync() vs .Read()

Oren F.

Test Conditions:

.NET Core 2, Console Application

SQL Server 2008 R2: Yes, this needs updating but there is still important information here including async all the way isn't necessarily the best idea for every situation.

Test Application Code:

4 x 100 paralleled queries, 1000 records each query.

       static void Main(string[] args)
       {
           var repeat = 4;
           var parallel = 100;
           var time = new ConcurrentBag<TimeSpan>();
           var totalTime = Stopwatch.StartNew();
           for(var x = 0; x< repeat; x++)
           {
               Console.Write("{0}) ", x);
               Parallel.For(0, parallel, i =>
               {
                   var sw = Stopwatch.StartNew();
                   // Query code goes here. Example: SELECT TOP 1000 * FROM Product
                   time.Add(sw.Elapsed);
               });
               Console.WriteLine("complete", x);
           }
           Console.WriteLine();
           Console.WriteLine("Total Time: {0}", totalTime.Elapsed);
           Console.WriteLine("Average Query: {0}",
time.Aggregate((a, b) => a + b) / parallel / 4);
           Console.WriteLine();
           Console.WriteLine("Press ENTER to continue.");
           Console.ReadLine();
       }

Results:

Baseline

NOTE: The CommandBehavior.Default versions of the following tests were only slightly slower on all metrics.


.Open()
.ExecuteReader(CommandBehavior.SequentialAccess)
while(reader.Read())
reader.GetValues(array)


Total Time: 00:00:25.1435656
Average Query: 00:00:00.6731697


await .OpenAsync()
await .ExecuteReaderAsync(CommandBehavior.SequentialAccess)
while(reader.Read())
reader.GetValues(array)


Total Time: 00:00:30.2188467
Average Query: 00:00:01.4122918


await .OpenAsync()
await .ExecuteReaderAsync(CommandBehavior.SequentialAccess)
while(await reader.ReadAsync())
reader.GetValues(array)


Total Time: 00:00:32.6702872
Average Query: 00:00:02.6879162

Assessment

Again, this is a SQL Server 2008 R2 instance but the obvious evidence here is:

The fully asynchronous approach not only takes longer in total time and per query, but uses up a significant amount more of CPU time.

This suggests that for operations like extracting data, using async methods within iterations should be scrutinized heavily.

Report Page