C# 由于派生表,实体框架速度较慢
我使用的是带有LINQtoEntities的MySQL Connector/NET6.5.4,我经常会得到糟糕的查询性能,因为entity框架生成的查询使用派生表 下面是我多次遇到的一个简化示例。在C语言中,我编写了如下查询:C# 由于派生表,实体框架速度较慢,c#,mysql,entity-framework,linq-to-entities,database-performance,C#,Mysql,Entity Framework,Linq To Entities,Database Performance,我使用的是带有LINQtoEntities的MySQL Connector/NET6.5.4,我经常会得到糟糕的查询性能,因为entity框架生成的查询使用派生表 下面是我多次遇到的一个简化示例。在C语言中,我编写了如下查询: var culverCustomers = from cs in db.CustomerSummaries where cs.Street == "Culver" select cs; // later... var sortedCustomers = culverCus
var culverCustomers = from cs in db.CustomerSummaries where cs.Street == "Culver" select cs;
// later...
var sortedCustomers = culverCustomers.OrderBy(cs => cs.Name).ToList();
SELECT cust.id FROM customer_summary cust WHERE cust.street = "Culver" ORDER BY cust.name
SELECT Project1.id FROM (
SELECT cust.id, cust.name, cust.street FROM customer_summary cust
WHERE Project1.street = "Culver"
) AS Project1 -- here is where the EF generates a pointless derived table
ORDER BY Project1.name
而不是生成这样的简单查询:
var culverCustomers = from cs in db.CustomerSummaries where cs.Street == "Culver" select cs;
// later...
var sortedCustomers = culverCustomers.OrderBy(cs => cs.Name).ToList();
SELECT cust.id FROM customer_summary cust WHERE cust.street = "Culver" ORDER BY cust.name
SELECT Project1.id FROM (
SELECT cust.id, cust.name, cust.street FROM customer_summary cust
WHERE Project1.street = "Culver"
) AS Project1 -- here is where the EF generates a pointless derived table
ORDER BY Project1.name
实体框架使用如下派生表生成查询:
var culverCustomers = from cs in db.CustomerSummaries where cs.Street == "Culver" select cs;
// later...
var sortedCustomers = culverCustomers.OrderBy(cs => cs.Name).ToList();
SELECT cust.id FROM customer_summary cust WHERE cust.street = "Culver" ORDER BY cust.name
SELECT Project1.id FROM (
SELECT cust.id, cust.name, cust.street FROM customer_summary cust
WHERE Project1.street = "Culver"
) AS Project1 -- here is where the EF generates a pointless derived table
ORDER BY Project1.name
如果我解释这两个查询,第一个查询会得到:
id, select_type, table, type, possible_keys, rows
1, PRIMARY, addr, ALL, PRIMARY, 9
1, PRIMARY, cust, ref, PRIMARY, 4
。。。对于实体框架查询来说,像这样糟糕的事情
id, select_type, table, type, possible_keys, rows
1, PRIMARY, <derived2>, ALL, 9639
2, DERIVED, addr, ALL, PRIMARY, 9
2, DERIVED, cust, ref, PRIMARY, 4
我认为您的查询语句缺少“select”。您尚未确定所需的记录。 您的查询:
var culverCustomers = from cs in db.CustomerSummaries
where cs.Street == "Culver";
//无选择
你从表中选择了什么?试试这个
例如:
var culverCustomers = from cs in db.CustomerSummaries
where cs.Street == "Culver"
select cs;
仅供参考,但它仍然不如其他一些数据库服务器。谢谢!我会尝试一下,看看是否有改进。你推荐什么?我有一些灵活性。我只能说这是MS SQL Server能够做到的。在MSSQL上,EF使用相同类型的生成SQL,但它在这方面工作得很好,而且如果使用实体框架,这可能是最受支持的数据库服务器。不过,很可能还有其他原因让您觉得这是一个糟糕的选择,所以不要把这当作一个硬性的建议。我将所有东西都迁移到了SQL Server上,速度明显提高了10-20倍。我认为MySql+EF足以满足我的适度需求最大的表是100个数千行,但connector/.net在性能和缺少的功能方面一再出现不足。SQL Server在收到查询时会执行查询优化。这种优化非常聪明,它不需要派生表。因此,SQLServer创建了一个新的查询计划,该计划工作得更好。LINQtoSQL和LINQtoEntities假设数据库将像SQLServer一样完成大部分查询优化。SQL Server、Oracle和其他高级数据库具有强大的查询优化功能:MySQL、Access和其他低成本数据库没有。这是否消除了OP提到的派生表?缺少的select是LINQ中的复制/粘贴错误。如果没有select子句,它甚至无法编译。我在原问题中添加了select子句以防止混淆。