1

ページングを実装するために、EF CodeFirst でTakeandステートメントを使用しています ( Zoran Maksimovicがこの投稿で述べたように)。これらのステートメントにより、EF は次のような SQL クエリを生成します (私のページ サイズは 100 です)。Skip

 SELECT TOP (100) [Filter1].[Id]                AS [Id],
                  [Filter1].[SendDuration]      AS [SendDuration]
        FROM   (SELECT [Extent1].[Id] AS [Id],               
                       [Extent1].[SendDuration] AS [SendDuration],
                       row_number() OVER (ORDER BY [Extent1].[SendDuration] DESC) AS [row_number]
                       FROM   [dbo].[MyView] AS [Extent1]
                       WHERE  (1293>= [Extent1].[Id])
                )AS [Filter1]
                WHERE  [Filter1].[row_number] > 500
                ORDER  BY [Filter1].[SendDuration] DESC

しかし、このSQLはSQLサーバーで実行すると非常に遅くなりますが、Boanergeがコメントで述べたように、row_number < X代わりに使用するTop(y)とパフォーマンスが向上します。つまり、生成されたSQLを次のように変更すると:

     SELECT  [Filter1].[Id]                AS [Id],
                  [Filter1].[SendDuration]      AS [SendDuration]
        FROM   (SELECT [Extent1].[Id] AS [Id],               
                       [Extent1].[SendDuration] AS [SendDuration],
                       row_number() OVER (ORDER BY [Extent1].[SendDuration] DESC) AS [row_number]
                       FROM   [dbo].[MyView] AS [Extent1]
                       WHERE  (1293>= [Extent1].[Id])
                )AS [Filter1]
                WHERE  [Filter1].[row_number] > 500 and [Filter1].[row_number] <= 600
                ORDER  BY [Filter1].[SendDuration] DESC

クエリの実行時間が改善され、許容範囲が広がります (場合によっては 4 倍または 5 倍速くなります)。EF に 1 番目の Sql ではなく 2 番目の Sql を強制的に生成させる方法はありますか?

4

2 に答える 2

1

これは、アルゴリズムによるクエリ生成の二重の利点です。クエリは、アルゴリズムと同じくらい優れています。それを変更する唯一の方法は、アルゴリズムが別のことを行うことを決定した場合です。おそらく、別のバージョンの ORM ツールを使用します。もちろん、「異なる」と「より良い」は必ずしも同じではありません:)

重要なクエリの場合、経験豊富な SQL 開発者は、適切なツール (SSMS は必要なもののほとんどを提供します) を備えていれば、多くの生成されたクエリよりも優れたパフォーマンスを発揮できます。もちろん、経験の浅い SQL 開発者は、クエリが間違った動作をすることになる可能性があります。

ほとんどの ORM は、生の SQL クエリをエンジンに渡すオプションを提供しますが、移植性は失われます。それが問題である場合、別のオプションはストアド プロシージャのようなもので、異なるデータベースの異なる実装でも API が類似している可能性があります。

ここで尋ねる必要がある質問は次のとおりです。

  • 本当に複数のデータベース プロバイダーをターゲットにしているのでしょうか?
  • このクエリの継続的なメンテナンスを所有してもよろしいですか?

答えが「いいえ」または「はい」の場合は、生の SQL (おそらく T-SQL) クエリを EF に渡すだけで問題ありません。

于 2013-06-23T08:32:07.510 に答える