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

我使用的是带有LINQtoEntities的MySQL Connector/NET6.5.4,我经常会得到糟糕的查询性能,因为entity框架生成的查询使用派生表

下面是我多次遇到的一个简化示例。在C语言中,我编写了如下查询:

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子句以防止混淆。