当使用活动记录与simplerepository查询时,任何人都知道为什么linq查询的速度大约慢6倍? 以下代码运行速度比使用简单存储库查询数据时慢6倍。此代码在循环中执行1000次
提前致谢
string ret = "";
// if (plan == null)
{
plan =VOUCHER_PLAN.SingleOrDefault(x => x.TENDER_TYPE == tenderType);
}
if (plan == null)
throw new InvalidOperationException("voucher type does not exist." + tenderType);
seq = plan.VOUCHER_SEQUENCES.First();
int i = seq.CURRENT_NUMBER;
seq.CURRENT_NUMBER += seq.STEP;
seq.Save();
答案 0 :(得分:2)
我们对此进行了一些分析,发现SubSonic的记录.SingleOrDefault(x => x.id = someval)比通过CodingHorror完成的同一查询慢20倍。在此处记录:https://github.com/subsonic/SubSonic-3.0/issues/258。
分析器在ExecutionBuilder.cs中指出了这一点:
// this sucks, but since we don't track true SQL types through the query, and ADO throws exception if you
// call the wrong accessor, the best we can do is call GetValue and Convert.ChangeType
Expression value = Expression.Convert(
Expression.Call(typeof (Convert), "ChangeType", null,
Expression.Call(reader, "GetValue", null, Expression.Constant(iOrdinal)),
Expression.Constant(TypeHelper.GetNonNullableType(column.Type), typeof(Type))
),
column.Type
);
令人失望,因为我非常喜欢SubSonic / Linq。
最后我们放弃了,我写了这个 - http://www.toptensoftware.com/petapoco。移植后,我们的负载测试显示每秒请求数增加,CPU负载从大约80%下降到5%。
答案 1 :(得分:0)
通过在构造函数/ init过程中缓存它创建的数据库实例,我能够在性能上产生巨大的差异。我现在看到的是加速2-3倍,取决于情况和运行。
1)如果只调用默认构造函数,只需用静态实例替换_db的方法就可以正常工作,并具有相同的速度优势。
// MyProject.MyDB _db;
// replace with a static instance, and remove the "this." from other lines
static MyProject.MyDB _db = new MyDB();
public MyClass() {
//_db=new MyProject.MyDB();
Init();
}
2)我为数据库条目编写了一个小缓存类,并在使用“new()”的所有旧位置从我的ActiveRecord.tt文件中调用它。
// REPLACE "MyDB" with the name of your DB. Alternately, include this
// class in Context.tt and have it generate the correct name.
class ContextDatabaseCache {
public static MyDB GetMyDB()
{
return GetInstance("~~default~~", () => new MyDB());
}
public static MyDB GetMyDB(string connectionString) {
return GetInstance(connectionString, () => new MyDB(connectionString));
}
public static MyDB GetMyDB(string connectionString, string providerName)
{
return GetInstance(connectionString + providerName, () => new MyDB(connectionString, providerName));
}
private static Dictionary<string, MyDB> _dict = new Dictionary<string, MyDB>();
private static MyDB GetInstance(string key, Func<MyDB> createInstance)
{
if (!_dict.ContainsKey(key)) {
lock (_dict) {
if (!_dict.ContainsKey(key)) {
_dict.Add(key, createInstance());
}
}
}
return _dict[key];
}
///<summary>Call this when the "DefaultConnection" string changes in the
/// App.exe.config file so that a new db instance will be created
/// and pick up the changed value. </summary>
public static void Clear() {
_dict.Clear();
}
}
这是在ActiveRecord.tt文件中进行的替换类型:
public <#=tbl.ClassName#>(){
_db=new <#=Namespace#>.<#=DatabaseName#>DB();
Init();
}
// becomes this:
public <#=tbl.ClassName#>(){
_db= <#=Namespace#>.ContextDatabaseCache.Get<#=DatabaseName#>DB();
Init();
}
答案 2 :(得分:0)
显然这对于亚音速来说“不是问题”,尽管他们知道它存在。它不会被修复。你必须使用一个糟糕的批处理查询语法来获得这个,没有人会这样做。
我不明白的是,这是90%的情况。从表中获取记录列表。它应该 BE 是快速的,而不是慢的。无论何时何地,每个人都会这样做。
亚音速问题很多。我不得不为DB field =&gt;编写缓存对象字段查找,因为它们也非常缓慢。