During migration from Mysql.Data we got performance issue in code that reads the first row from a SQL query using Dapper method QueryFirstOrDefaultAsync. With Oracle driver execution time is about 600 ms but with MySqlConnector execution time is about 50 seconds.
After some investigation I found that the problem is inside MySqlCommand.ExecuteReaderAsync. Here is the app I use to reproduce the issue:
using System;
using System.Data;
using System.Diagnostics;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
namespace MysqlConnIssue
{
class Program
{
static async Task Main(string[] args)
{
object result = null;
var rand = new Random();
using (var conn = new MySqlConnection("you conn str"))
{
await conn.OpenAsync();
// table users contains 400K rows , _Ids - 1K rows
// a random value is used to disable query caching in mysql
using (var cmd = new MySqlCommand($@"
SELECT IntegerValue
FROM _Ids
WHERE IntegerValue NOT IN
(SELECT userid FROM users WHERE userid <> {rand.Next()})", conn))
{
var sw = new Stopwatch();
sw.Start();
// ExecuteReaderAsync is about 100 times slower when MySqlConnector is referenced
var reader = await cmd.ExecuteReaderAsync(CommandBehavior.SingleRow);
Console.WriteLine($"ExecuteReader: {sw.ElapsedMilliseconds}ms");
sw.Restart();
if (await reader.ReadAsync())
{
result = reader[0];
}
Console.WriteLine($"Read: {sw.ElapsedMilliseconds}ms");
}
}
Console.WriteLine($"Result: {result}");
}
}
}
Workaround is adding LIMIT 1 to the query but it will require to review all code we have
During migration from
Mysql.Datawe got performance issue in code that reads the first row from a SQL query using Dapper methodQueryFirstOrDefaultAsync. With Oracle driver execution time is about 600 ms but with MySqlConnector execution time is about 50 seconds.After some investigation I found that the problem is inside MySqlCommand.ExecuteReaderAsync. Here is the app I use to reproduce the issue:
Workaround is adding
LIMIT 1to the query but it will require to review all code we have