[解決済み] ページングの効率的な実装方法
質問
LINQの
Skip()
と
Take()
メソッドでページングを行うか、SQLクエリで独自のページングを実装しますか?
どちらが最も効率的ですか?なぜどちらかを選ぶのでしょうか?
SQL Server 2008、ASP.NET MVC、LINQを使用しています。
どのように解決するのですか?
あなたの疑問に対する簡単な答えを出そうとすると、もしあなたが
skip(n).take(m)
メソッドを linq で実行した場合 (SQL 2005 / 2008 をデータベースサーバーとした場合)、クエリは
Select ROW_NUMBER() Over ...
ステートメントを使用し、SQL エンジンで何らかの形で直接ページングされます。
例を挙げると、私は以下のようなDBテーブルを持っています。
mtcity
という名前のテーブルがあり、次のようなクエリを書きました(linq to entitiesでも同様に動作します)。
using (DataClasses1DataContext c = new DataClasses1DataContext())
{
var query = (from MtCity2 c1 in c.MtCity2s
select c1).Skip(3).Take(3);
//Doing something with the query.
}
結果のクエリーは
SELECT [t1].[CodCity],
[t1].[CodCountry],
[t1].[CodRegion],
[t1].[Name],
[t1].[Code]
FROM (
SELECT ROW_NUMBER() OVER (
ORDER BY [t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]) AS [ROW_NUMBER],
[t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]
FROM [dbo].[MtCity] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]
これはウィンドウデータアクセスです(非常にクールな、btw cuzは非常に最初からデータを返し、条件が満たされている限り、テーブルにアクセスします)。これは非常に似ています。
With CityEntities As
(
Select ROW_NUMBER() Over (Order By CodCity) As Row,
CodCity //here is only accessed by the Index as CodCity is the primary
From dbo.mtcity
)
Select [t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]
From CityEntities c
Inner Join dbo.MtCity t0 on c.CodCity = t0.CodCity
Where c.Row Between @p0 + 1 AND @p0 + @p1
Order By c.Row Asc
例外として、この2番目のクエリはデータアクセスウィンドウを作成するためにインデックスのみを使用するため、linqの結果よりも速く実行されます。これは、何らかのフィルタリングが必要な場合、フィルタリングはエンティティリスト(行の作成場所)にあるべき(またはなければならない)で、良い性能を維持するためにはいくつかのインデックスも作成しなければならないことを意味しています。
さて、何が良いのでしょうか?
ロジックにかなりしっかりしたワークフローがある場合、適切なSQLの方法を実装するのは複雑になります。その場合、LINQが解決策になります。
ロジックのその部分を直接SQLに落とすことができれば(ストアドプロシージャで)、私が示した2番目のクエリを実装でき(インデックスを使用)、SQLがクエリの実行計画を生成して保存できるため(パフォーマンスを改善)、さらに良くなるでしょう。
関連
-
MySQL】1136 - 列数が1行目の値数と一致しない問題を解決
-
[解決済み] SQL ServerでSELECTからUPDATEする方法とは?
-
[解決済み] SQL Server - 挿入された行のIDを取得するための最良の方法は?
-
[解決済み] SQL Server における DateTime2 と DateTime の比較
-
[解決済み] SQL ServerにおけるINSERT OR UPDATEに関する解決策
-
[解決済み] ASP.NET MVC - カスタムIIdentityまたはIPrincipalの設定
-
[解決済み] SQL Serverでは、MONEYとDECIMAL(x,y)のどちらをデータ型として選択すべきでしょうか?
-
[解決済み] ASP.NET MVCのビューを文字列としてレンダリングする方法は?
-
[解決済み] SQL ServerでINSERT INTOとしてデータをエクスポートする
-
[解決済み】マルチインデックスとマルチカラムインデックスの比較
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Oracle Trigger ORA-04098: トリガーが無効で、再バリデーションに失敗しました。
-
[解決済み] SQL Server の DateTime データ型から日付だけを返す方法
-
[解決済み] テーブルネーミングのジレンマ:単数形と複数形の名前【非公開
-
[解決済み] SQL ServerでJOINを使用してUPDATE文を実行するにはどうすればよいですか?
-
[解決済み] INNER JOINよりもCROSS APPLYを使用すべきなのはどのような場合ですか?
-
[解決済み] SQL Serverにおける関数とストアドプロシージャの比較
-
[解決済み] MySQLでFULL OUTER JOINを行うにはどうすればよいですか?
-
[解決済み] SQL Serverで結果をページ分割する最も良い方法は何ですか?
-
[解決済み] 文字列の一部をUPDATEおよびREPLACEする。
-
[解決済み] このクエリを使用してページング(スキップ/テイク)機能を実装する