2

Entity Framework から SQL にほぼ 1 対 1 で変換したい次のクエリがあります。

SELECT GroupId, ItemId, count(*) as total
  FROM [TESTDB].[dbo].[TestTable]
  WHERE GroupId = '64025'
  GROUP BY GroupId, ItemId
  ORDER BY GroupId, total DESC

ItemIdこの SQL クエリは、同じ(そのグループの)出現回数に基づいてソートする必要があります。

私は今これを持っています:

from x in dataContext.TestTable.AsNoTracking()
where x.GroupId = 64025
group x by new {x.GroupId, x.ItemId}
into g
orderby g.Key.GroupId, g.Count() descending 
select new {g.Key.GroupId, g.Key.ItemId, Count = g.Count()};

しかし、これにより次の SQL コードが生成されます。

SELECT 
  [GroupBy1].[K1] AS [GroupId], 
  [GroupBy1].[K2] AS [ItemId], 
  [GroupBy1].[A2] AS [C1]
FROM ( SELECT 
         [Extent1].[GroupId] AS [K1], 
         [Extent1].[ItemId] AS [K2], 
         COUNT(1) AS [A1], 
         COUNT(1) AS [A2]
       FROM [dbo].[TestTable] AS [Extent1]
       WHERE 64025 = [Extent1].[GroupId]
       GROUP BY [Extent1].[GroupId], [Extent1].[ItemId]
     )  AS [GroupBy1]
ORDER BY [GroupBy1].[K1] ASC, [GroupBy1].[A1] DESC

これも機能しますが、作成した SQL よりも 2 倍遅くなります。

私はしばらくlinqコードをいじっていましたが、クエリに似たものを作成できませんでした。

実行計画 (最後の 2 つの項目のみ、最初の 2 つの項目は同一):

FIRST:   |--Stream Aggregate(GROUP BY:([Extent1].[ItemId]) DEFINE:([Expr1006]=Count(*), [Extent1].[GroupId]=ANY([TESTDB].[dbo].[TestTable].[GroupId] as [Extent1].[GroupId])))
           |--Index Seek(OBJECT:([TESTDB].[dbo].[TestTable].[IX_Group]), SEEK:([TESTDB].[dbo].[TestTable].[GroupId]=(64034)) ORDERED FORWARD)

SECOND:  |--Stream Aggregate(GROUP BY:([TESTDB].[dbo].[TestTable].[ItemId]) DEFINE:([Expr1007]=Count(*), [TESTDB].[dbo].[TestTable].[GroupId]=ANY([TESTDB].[dbo].[TestTable].[GroupId])))
           |--Index Seek(OBJECT:([TESTDB].[dbo].[TestTable].[IX_Group] AS [Extent1]), SEEK:([Extent1].[GroupId]=(64034)) ORDERED FORWARD)
4

1 に答える 1

4

Entity Framework が生成するクエリと手作りのクエリは、意味的に同じであり、同じプランを提供します。

派生テーブルの定義は、クエリの最適化中にインライン化されるため、唯一の違いは、解析およびコンパイル中の非常にわずかな追加オーバーヘッドである可能性があります。

SHOWPLAN_TEXTあなたが投稿したスニペットは同じ計画です。唯一の違いはエイリアスです。テーブル定義は次のようになります。

CREATE TABLE [dbo].[TestTable] 
(
[GroupId] INT,
[ItemId] INT
)

CREATE NONCLUSTERED INDEX IX_Group ON  [dbo].[TestTable] ([GroupId], [ItemId]) 

そして、あなたはこのような計画を得ています

プラン

すべての意図と目的に対して、計画は同じです。パフォーマンス テストの方法論に欠陥がある可能性があります。たとえば、最初のクエリでページがキャッシュに取り込まれ、それが 2 番目のクエリに利益をもたらした可能性があります。

于 2013-01-06T15:12:00.630 に答える