エンティティへの LINQ で MySQL Connector/Net 6.5.4 を使用していますが、エンティティ フレームワークが派生テーブルを使用するクエリを生成するため、頻繁にクエリのパフォーマンスが低下します。
これは、私が何度か遭遇した単純な例です。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
両方のクエリを説明すると、最初のクエリで次のようになります。
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
MySQL が9000+ レコードをスキャンしていると説明している最初の行に注目してください。派生テーブルのため、MySQL は一時テーブルを作成し、すべての行をロードします。(または、次のような記事に基づいて推測しています: Derived Tables and Views Performance )
Entity Framework が派生テーブルを使用しないようにするにはどうすればよいですか? または、このようなクエリに対して明らかな最適化を行うように MySQL を説得するにはどうすればよいでしょうか?
完了するために、この linq クエリのソースであるビューを次に示します。
create view customer_summary as
select cust.id, cust.name, addr.street
customers cust
join addresses addr
on addr.customer_id = cust.id