そのため、SQLServerデータベースにアクセスするためのさまざまな方法のプロファイリングを行っていました。バニラTSQL、CompiledQuery、およびコンパイルされていないLinqステートメントを実行しました。
予想通り、パフォーマンスは同じ順序で進んでいましたが、後者の2つをプロファイリングすると、何か不思議なことに気づきました。
CompiledQueryによって生成されたSQLは、単純な古いステートメントによって生成されたものよりもはるかに優れていました。
ローカルSQLExpressデータベース。テーブルは「foreignTable」と呼ばれ、ColumnAはint、主キー(インデックス付き)です。ColumnBはランダムなintです。
Func<testingDatabaseEntities1, int, int> GetByPK = CompiledQuery.Compile((testingDatabaseEntities1 ft, int key)
=> (ft.foreignTable.Where(x => x.ColumnA == key).FirstOrDefault().ColumnB));
生成します
SELECT
[Project1].[ColumnB] AS [ColumnB]
FROM ( SELECT cast(1 as bit) AS X ) AS [SingleRowTable1]
LEFT OUTER JOIN (SELECT TOP (1)
[Extent1].[ColumnB] AS [ColumnB]
FROM [dbo].[foreignTable] AS [Extent1]
WHERE [Extent1].[ColumnA] = @p__linq__1 ) AS [Project1] ON 1 = 1
これは、生成されたコードの場合、実際にはそれほどひどいものではありません。
しかし、私が単純なLinqステートメントを実行すると:
entity.foreignTable.Where(x => x.ColumnA == searchForMe).FirstOrDefault().ColumnB
それは生成します:
SELECT
[Limit1].[C1] AS [C1],
[Limit1].[ColumnA] AS [ColumnA],
[Limit1].[ColumnB] AS [ColumnB],
[Limit1].[FKColumn] AS [FKColumn]
FROM ( SELECT TOP (1)
[Extent1].[ColumnA] AS [ColumnA],
[Extent1].[ColumnB] AS [ColumnB],
[Extent2].[FKColumn] AS [FKColumn],
1 AS [C1]
FROM [dbo].[foreignTable] AS [Extent1]
LEFT OUTER JOIN (SELECT
[Table_2].[FKColumn] AS [FKColumn],
[Table_2].[SomeText] AS [SomeText]
FROM [dbo].[Table_2] AS [Table_2]) AS [Extent2] ON [Extent1].[ColumnA] = [Extent2].[FKColumn]
WHERE [Extent1].[ColumnA] = @p__linq__7
) AS [Limit1]
これはただくだらないです。
ですから、質問は次のように思います。通常のLinqをエンティティにCompiledQueryと同じ量のSQLサッキーを与えることは可能ですか?