完成优化自动追踪性能提升1000%并且发布了x.3.0.5版本

This commit is contained in:
xuejiaming 2021-10-08 13:15:17 +08:00
parent 2a13b37ba4
commit 4300290cc6
10 changed files with 87 additions and 24 deletions

View File

@ -1,8 +1,8 @@
:start
::定义版本
set EFCORE2=2.3.0.04
set EFCORE3=3.3.0.04
set EFCORE5=5.3.0.04
set EFCORE2=2.3.0.05
set EFCORE3=3.3.0.05
set EFCORE5=5.3.0.05
::删除所有bin与obj下的文件
@echo off

View File

@ -30,6 +30,7 @@ namespace Sample.BulkConsole
{
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
o.AutoTrackEntity = true;
})
.AddShardingQuery((conStr, builder) => builder.UseSqlServer(conStr).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking))
.AddShardingTransaction((connection, builder) => builder.UseSqlServer(connection))
@ -80,8 +81,40 @@ namespace Sample.BulkConsole
var b = DateTime.Now.Date.AddDays(-3);
var queryable = myShardingDbContext.Set<Order>().Where(o => o.CreateTime >= b).OrderBy(o => o.CreateTime);
var startNew1 = Stopwatch.StartNew();
startNew1.Restart();
var list2 = queryable.Take(1000).ToList();
startNew1.Stop();
Console.WriteLine($"获取1000条用时:{startNew1.ElapsedMilliseconds}毫秒");
startNew1.Restart();
var list = queryable.Take(10).ToList();
startNew1.Stop();
Console.WriteLine($"获取10条用时:{startNew1.ElapsedMilliseconds}毫秒");
startNew1.Restart();
var list1 = queryable.Take(100).ToList();
startNew1.Stop();
Console.WriteLine($"获取100条用时:{startNew1.ElapsedMilliseconds}毫秒");
startNew1.Restart();
var list3 = queryable.Take(10000).ToList();
startNew1.Stop();
Console.WriteLine($"获取100000条用时:{startNew1.ElapsedMilliseconds}毫秒");
startNew1.Restart();
var list4 = queryable.Take(20000).ToList();
startNew1.Stop();
Console.WriteLine($"获取20000条用时:{startNew1.ElapsedMilliseconds}毫秒");
int skip = 0, take = 1000;
for (int i = 20000; i < 30000; i++)
{

View File

@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="EFCore.BulkExtensions" Version="5.3.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,8 +1,10 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
using Microsoft.EntityFrameworkCore.Internal;
@ -155,16 +157,38 @@ namespace ShardingCore.Extensions
private static object sLock = new object();
public static IEnumerable<object> GetPrimaryKeyValues<TEntity>(TEntity entity,IKey primaryKey) where TEntity : class
{
return primaryKey.Properties.Select(o => entity.GetPropertyValue(o.Name));
}
public static TEntity GetAttachedEntity<TEntity>(this DbContext context, TEntity entity) where TEntity:class
{
if (entity == null) { throw new ArgumentNullException(nameof(entity)); }
var primaryKeyValue = ShardingKeyUtil.GetPrimaryKeyValues(entity);
var entityPrimaryKey = context.Model.FindEntityType(entity.GetType()).FindPrimaryKey();
var primaryKeyValue = GetPrimaryKeyValues(entity, entityPrimaryKey).ToArray();
if (primaryKeyValue.IsEmpty())
return null;
var entry = context.ChangeTracker.Entries<TEntity>().FirstOrDefault(e =>e.State != EntityState.Detached&&primaryKeyValue.SequenceEqual(ShardingKeyUtil.GetPrimaryKeyValues(e.Entity)));
var dbContextDependencies = (IDbContextDependencies)typeof(DbContext).GetTypePropertyValue(context, "DbContextDependencies");
var stateManager = dbContextDependencies.StateManager;
//var entityIKey = ShardingKeyUtil.GetEntityIKey(entity);
var internalEntityEntry = stateManager.TryGetEntry(entityPrimaryKey, primaryKeyValue);
if (internalEntityEntry == null)
return null;
return (TEntity)internalEntityEntry.Entity;
//sp.Restart();
return entry?.Entity;
//var entityEntries = context.ChangeTracker.Entries<TEntity>();
//sp.Stop();
//Console.WriteLine($"ChangeTracker.Entries:{sp.ElapsedMilliseconds}毫秒");
//sp.Restart();
//var entry = entityEntries.Where(e => e.State != EntityState.Detached && primaryKeyValue.SequenceEqual(ShardingKeyUtil.GetPrimaryKeyValues(e.Entity))).FirstOrDefault();
//sp.Stop();
//Console.WriteLine($"ChangeTracker.FirstOrDefault:{sp.ElapsedMilliseconds}毫秒");
//return entry?.Entity;
}
}

View File

@ -1,14 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.TrackerManagers;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Sharding.StreamMergeEngines.TrackerEnumerators
namespace ShardingCore.Sharding.Enumerators.TrackerEnumerators
{
/*
* @Author: xjm

View File

@ -1,11 +1,8 @@
using System;
using System.Collections;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Extensions;
namespace ShardingCore.Sharding.StreamMergeEngines.TrackerEnumerators
namespace ShardingCore.Sharding.Enumerators.TrackerEnumerators
{
/*
* @Author: xjm
@ -51,7 +48,9 @@ namespace ShardingCore.Sharding.StreamMergeEngines.TrackerEnumerators
var genericDbContext = _streamMergeContext.GetShardingDbContext().CreateGenericDbContext(c);
var attachedEntity = genericDbContext.GetAttachedEntity(c);
if (attachedEntity == null)
{
genericDbContext.Attach(current);
}
else
{
return (T)attachedEntity;

View File

@ -3,8 +3,8 @@ using System.Collections.Generic;
using System.Threading;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.Enumerators.TrackerEnumerators;
using ShardingCore.Sharding.ShardingQueryExecutors;
using ShardingCore.Sharding.StreamMergeEngines.TrackerEnumerators;
namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
{

View File

@ -228,14 +228,16 @@ namespace ShardingCore.Sharding
}
private bool QueryTrack()
{
var shardingDbContext = (DbContext)_shardingDbContext;
if (!shardingDbContext.ChangeTracker.AutoDetectChangesEnabled)
return false;
if (IsNoTracking.HasValue)
{
return !IsNoTracking.Value;
}
else
{
return ((DbContext)_shardingDbContext).ChangeTracker.QueryTrackingBehavior ==
return shardingDbContext.ChangeTracker.QueryTrackingBehavior ==
QueryTrackingBehavior.TrackAll;
}
}

View File

@ -78,7 +78,7 @@ namespace ShardingCore
EnsureCreated(context, dataSourceName);
foreach (var entity in context.Model.GetEntityTypes())
{
ShardingKeyUtil.ParsePrimaryKeyName(entity);
//ShardingKeyUtil.ParsePrimaryKeyName(entity);
var entityType = entity.ClrType;
//添加追踪模型
_trackerManager.AddDbContextModel(entityType);

View File

@ -44,6 +44,16 @@ namespace ShardingCore.Utils
return primaryKey.Properties.Select(o => entity.GetPropertyValue(o.Name));
}
public static IKey GetEntityIKey(object entity)
{
var entityType = entity.GetType();
if (!_caches.TryGetValue(entityType, out var primaryKey))
{
return null;
}
return primaryKey;
}