sharding/benchmarks/ShardingCoreBenchmark/EFCoreCrud.cs

481 lines
20 KiB
C#

using BenchmarkDotNet.Attributes;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using ShardingCore;
using ShardingCore.Extensions;
using ShardingCore6x.NoShardingDbContexts;
using ShardingCore6x.ShardingDbContexts;
using System.Diagnostics;
namespace ShardingCore6x
{
public class EFCoreCrud
{
private readonly DefaultDbContext _defaultDbContext;
private readonly DefaultShardingDbContext _defaultShardingDbContext;
private readonly ServiceCollection services;
public EFCoreCrud()
{
services = new ServiceCollection();
services.AddDbContext<DefaultDbContext>(o => o
//.UseMySql("server=127.0.0.1;port=3306;database=db1;userid=root;password=L6yBtV6qNENrwBy7;", new MySqlServerVersion(new Version()))
.UseSqlServer("Data Source=localhost;Initial Catalog=db1;Integrated Security=True;")
, ServiceLifetime.Transient, ServiceLifetime.Transient);
services.AddLogging();
services.AddShardingDbContext<DefaultShardingDbContext>(ServiceLifetime.Transient, ServiceLifetime.Transient)
.UseRouteConfig(o =>
{
o.AddShardingTableRoute<OrderVirtualTableRoute>();
})
.UseConfig(op =>
{
op.UseShardingQuery((conStr, builder) =>
{
builder.UseSqlServer(conStr);
//builder.UseMySql(conStr, new MySqlServerVersion(new Version()));
});
op.UseShardingTransaction((connection, builder) =>
{
builder.UseSqlServer(connection);
//builder.UseMySql(connection, new MySqlServerVersion(new Version()));
});
op.AddDefaultDataSource("ds0",
"Data Source=localhost;Initial Catalog=db2;Integrated Security=True;");
//op.AddDefaultDataSource("ds0", "server=127.0.0.1;port=3306;database=db2;userid=root;password=L6yBtV6qNENrwBy7;");
}).AddShardingCore();
var buildServiceProvider = services.BuildServiceProvider();
buildServiceProvider.UseAutoShardingCreate();
buildServiceProvider.UseAutoTryCompensateTable();
ICollection<Order> orders = new LinkedList<Order>();
using (var scope = buildServiceProvider.CreateScope())
{
var defaultShardingDbContext = scope.ServiceProvider.GetService<DefaultDbContext>();
defaultShardingDbContext.Database.EnsureCreated();
if (!defaultShardingDbContext.Set<Order>().Any())
{
var begin = DateTime.Now.Date.AddDays(-8);
var now = DateTime.Now;
var current = begin;
int i = 0;
var x = new OrderStatusEnum[] { OrderStatusEnum.Failed, OrderStatusEnum.NotPay, OrderStatusEnum.Succeed };
while (current < now)
{
orders.Add(new Order()
{
Id = i.ToString(),
Amount = i,
Body = $"今天购买了的东西呀:{i}",
CreateTime = current,
Remark = $"这是我的备注哦备注哦备注哦:{i}",
Payer = Guid.NewGuid().ToString("n"),
OrderStatus = x[i % 3]
});
i++;
current = current.AddMilliseconds(100);
}
var sp = Stopwatch.StartNew();
defaultShardingDbContext.BulkInsert<Order>(orders.ToList());
sp.Stop();
Console.WriteLine($"批量插入订单数据:{orders.Count},用时:{sp.ElapsedMilliseconds}");
}
}
using (var scope = buildServiceProvider.CreateScope())
{
var defaultShardingDbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>();
if (!defaultShardingDbContext.Set<Order>().Any())
{
var sp = Stopwatch.StartNew();
var bulkShardingEnumerable = defaultShardingDbContext.BulkShardingTableEnumerable(orders.ToList());
foreach (var keyValuePair in bulkShardingEnumerable)
{
keyValuePair.Key.BulkInsert(keyValuePair.Value.ToList());
}
sp.Stop();
Console.WriteLine($"批量插入订单数据:{orders.Count},用时:{sp.ElapsedMilliseconds}");
}
}
_defaultDbContext = buildServiceProvider.GetService<DefaultDbContext>();
_defaultShardingDbContext = buildServiceProvider.GetService<DefaultShardingDbContext>();
}
[Params(10)]
public int N;
//private static readonly string[] aa = new string[] { "a", "b", "c", "d" };
//[Benchmark]
//public void ShardingCreateDbContextFirstOrDefault()
//{
// for (int i = 0; i < N; i++)
// {
// var routeTail = _routeTailFactory.Create(aa[i % 4]);
// var dbContext = _defaultShardingDbContext.GetDbContext("ds0", true, routeTail);
// }
//}
//[Benchmark]
//public void ActualConnectionStringManager()
//{
// for (int i = 0; i < N; i++)
// {
// var connectionString = _actualConnectionStringManager.GetConnectionString("ds0", false);
// }
//}
//[Benchmark]
//public async Task CreateQueryable()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1000000, 3000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// }
//}
//[Benchmark]
//public async Task DataSourceRouteRuleEngineFactory()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1000000, 3000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// _dataSourceRouteRuleEngineFactory.Route(queryable);
// }
//}
//[Benchmark]
//public async Task TableRouteRuleEngineFactory()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1000000, 3000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// _tableRouteRuleEngineFactory.Route(queryable);
// }
//}
//[Benchmark]
//public async Task ShardingCreateStreamMergeContext()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1000000, 3000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// var firstOrDefaultAsync = _streamMergeContextFactory.Create(queryable, _defaultShardingDbContext);
// }
//}
//[Benchmark]
//public async Task NoRouteParseCache()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1, 3000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// _virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable));
// }
//}
//[Benchmark]
//public async Task ShardingFirstOrDefaultAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == "1000");
// _virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable));
// var queryable1 = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == "1000004");
// _virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable1));
// }
//}
//[Benchmark]
//public async Task NoShardingFirstOrDefaultAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1, 7000000).ToString();
// var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == next);
// }
//}
//[Benchmark]
//public async Task ShardingFirstOrDefaultAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1, 7000000).ToString();
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == next);
// }
//}
[Benchmark]
public async Task NoShardingIndexFirstOrDefaultAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1000000, 7000000).ToString();
var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == next);
}
}
[Benchmark]
public async Task ShardingIndexFirstOrDefaultAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1000000, 7000000).ToString();
var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == next);
}
}
[Benchmark]
public async Task NoShardingNoIndexFirstOrDefaultAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1000000, 7000000);
var firstOrDefaultAsync1 = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == next);
}
}
[Benchmark]
public async Task ShardingNoIndexFirstOrDefaultAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1000000, 7000000);
var firstOrDefaultAsync1 = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == next);
}
}
[Benchmark]
public async Task NoShardingNoIndexCountAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1000000, 7000000);
var firstOrDefaultAsync1 = await _defaultDbContext.Set<Order>().CountAsync(o => o.Amount == next);
}
}
[Benchmark]
public async Task ShardingNoIndexCountAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1000000, 7000000);
var firstOrDefaultAsync1 = await _defaultShardingDbContext.Set<Order>().CountAsync(o => o.Amount == next);
}
}
//[Benchmark]
//public async Task NoShardingNoIndexFirstOrDefaultAsync0w()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 0);
// }
//}
//[Benchmark]
//public async Task ShardingNoIndexFirstOrDefaultAsync0w()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 0);
// }
//}
//[Benchmark]
//public async Task NoShardingNoIndexFirstOrDefaultAsync99w()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 999999);
// }
//}
//[Benchmark]
//public async Task ShardingNoIndexFirstOrDefaultAsync99w()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 999999);
// }
//}
[Benchmark]
public async Task NoShardingNoIndexLikeToListAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 7000000).ToString();
var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().Where(o => o.Body.Contains(next)).ToListAsync();
}
}
[Benchmark]
public async Task ShardingNoIndexLikeToListAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 7000000).ToString();
var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().Where(o => o.Body.Contains(next)).ToListAsync();
}
}
[Benchmark]
public async Task NoShardingNoIndexToListAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 7000000);
var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().Where(o => o.Amount == next).ToListAsync();
}
}
[Benchmark]
public async Task ShardingNoIndexToListAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 7000000);
var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().Where(o => o.Amount == next).ToListAsync();
}
}
//[Benchmark]
//public void ShardingRouteFirstOrDefault()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1000000, 7000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// _virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable));
// }
//}
//private static readonly string[] aa = new string[] { "a", "b", "c", "d" };
//[Benchmark]
//public void ShardingCreateDbContextFirstOrDefault()
//{
// for (int i = 0; i < N; i++)
// {
// var routeTail = _routeTailFactory.Create(aa[i % 4]);
// var dbContext = _defaultShardingDbContext.GetDbContext("ds0", true, routeTail);
// }
//}
//[Benchmark]
//public async Task ShardingWhereFirstOrDefaultAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1000000, 7000000).ToString();
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next).FirstOrDefaultAsync();
// }
//}
//[Benchmark]
//public async Task ShardingCreateStreamMergeContext()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1000000, 7000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// var firstOrDefaultAsync = _streamMergeContextFactory.Create(queryable, _defaultShardingDbContext);
// }
//}
//[Benchmark]
//public async Task ShardingCreateEnumerableQuery()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1000000, 7000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// new EnumerableQuery<Order>(queryable.Expression);
// }
//}
//private TResult GenericShardingDbContextMergeExecute<TResult>(IQueryable<Order> queryable)
//{
// //{
// // var queryEntityType = query.GetQueryEntityType();
// //var newStreamMergeEngineType = streamMergeEngineType.MakeGenericType(shardingDbContext.GetType(), queryEntityType);
// //// {
// //// //获取所有需要路由的表后缀
// //// var startNew = Stopwatch.StartNew();
// //// for (int i = 0; i < 10000; i++)
// //// {
// //// var streamEngine = ShardingCreatorHelper.CreateInstance(newStreamMergeEngineType, query, shardingDbContext);
// //// }
// //// startNew.Stop();
// //// var x = startNew.ElapsedMilliseconds;
// //// }
// //{
// // //获取所有需要路由的表后缀
// // var startNew1 = Stopwatch.StartNew();
// // for (int i = 0; i < 10000; i++)
// // {
// // var streamEngine = Activator.CreateInstance(newStreamMergeEngineType, query, shardingDbContext);
// // }
// // startNew1.Stop();
// // var x = startNew1.ElapsedMilliseconds;
// //}
// // var methodName = async ? nameof(IGenericMergeResult.MergeResultAsync) : nameof(IGenericMergeResult.MergeResult);
// // var streamEngineMethod = newStreamMergeEngineType.GetMethod(methodName);
// // if (streamEngineMethod == null)
// // throw new ShardingCoreException($"cant found InMemoryAsyncStreamMergeEngine method [{methodName}]");
// // var @params = async ? new object[] { cancellationToken } : new object[0];
// //}
// {
// var queryEntityType = queryable.Expression.GetQueryEntityType();
// var newStreamMergeEngineType = streamMergeEngineType.MakeGenericType(shardingDbContext.GetType(), queryEntityType);
// var streamEngine = Activator.CreateInstance(newStreamMergeEngineType, query, shardingDbContext);
// var methodName = async ? nameof(IGenericMergeResult.MergeResultAsync) : nameof(IGenericMergeResult.MergeResult);
// var streamEngineMethod = newStreamMergeEngineType.GetMethod(methodName);
// if (streamEngineMethod == null)
// throw new ShardingCoreException($"cant found InMemoryAsyncStreamMergeEngine method [{methodName}]");
// var @params = async ? new object[] { cancellationToken } : new object[0];
// return (TResult)streamEngineMethod.MakeGenericMethod(new Type[] { queryEntityType }).Invoke(streamEngine, @params);
// }
//}
//[Benchmark]
//public async Task NoShardingNoTrackingFirstOrDefaultAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1, 3000000).ToString();
// var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().AsNoTracking().FirstOrDefaultAsync(o => o.Id == next);
// }
//}
//[Benchmark]
//public async Task ShardingNoTrackingFirstOrDefaultAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1, 3000000).ToString();
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().AsNoTracking().FirstOrDefaultAsync(o => o.Id == next);
// }
//}
//[Benchmark]
//public async Task NoShardingCountAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().CountAsync();
// }
//}
//[Benchmark]
//public async Task ShardingCountAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().CountAsync();
// }
//}
}
}