【发布时间】:2017-02-19 20:20:28
【问题描述】:
因此,有一些帖子抱怨 Entity Framework 6 的 MySQL 插件的性能。然而,其中大部分似乎归结为它生成了错误的 SQL。我遇到了这个问题,但这似乎是由于插件本身造成的性能滞后。
这是我在 LINQ 中的查询:
List<Address> matches = _rep.GetAddresses(s => s.AddressKey == cleanAddress).ToList();
在存储库中 (_rep) 我有这个:
public IQueryable<Address> GetAddresses(Expression<Func<Address, bool>> query)
{
//var foo = Addresses.AsNoTracking().Where(query);
//var bar = foo.ToString();
return Addresses.AsNoTracking().Where(query);
}
所以我已经在使用 AsNoTracking 来尝试提高性能。注释掉的行在那里,所以我可以看到正在生成的 SQL,结果是:
SELECT
`Extent1`.`AddressId`,
`Extent1`.`AddressKey`,
`Extent1`.`NameKey`,
`Extent1`.`Title`,
`Extent1`.`Forename`,
`Extent1`.`Surname`,
FROM `Addresses` AS `Extent1`
WHERE (`Extent1`.`AddressKey` = @p__linq__0)
OR ((`Extent1`.`AddressKey` IS NULL) AND (@p__linq__0 IS NULL))
足够简单。值得注意的是,AddressKey 是一个带有索引的 varchar(255) 列。
现在,事情就是这样。如果我将该查询插入 MySQL 工作台并运行它(使用不同的值 @p__linq__0),它甚至不会注册运行时间。它将持续时间列为 0.000 秒。
但是,在我的查询周围放置一个秒表并记录执行 Linq 所花费的时间大约为 0.004 秒。您可能认为差别不大,但这是运行此代码数百万次的速度关键型应用程序的一部分。很快就会加起来。
我对后面的 upsert 代码块有同样的问题。在工作台中本地运行,不到一毫秒。同样,通过 EF,它需要 3-4 毫秒。
我认为这归结于 EF MySQL 插件中的弱设计是否正确?如果是这样,如果我尝试将其更改为通过存储过程运行或直接使用ExecuteSqlCommand() 提交 SQL,我可以假设我会遇到同样的问题吗?
还有什么我可以尝试消除这种性能滞后的吗?
【问题讨论】:
-
您是指通过多次调用测量的平均时间,还是仅使用单个调用(可能是第一次调用有额外开销)?
-
@IvanStoev EF 记录的时间平均为 1k 次调用。 SQL 比较是几个单一的调用。我改变了它每次搜索的密钥,以尝试模仿 EF 在实际操作中所做的事情。
-
嗯,这只是一个猜测,但它实际上可能是 EF 查询执行/实现过程的开销,换句话说,与 MySQL 插件无关。您可以使用SqlQuery 甚至普通的
DbReader来衡量问题是否出在 EF 和/或 MySQL 插件中,但老实说,我认为您的要求/期望太高了。
标签: c# mysql entity-framework linq entity-framework-6