sql >> データベース >  >> RDS >> Sqlserver

ページングを実装する効率的な方法

    skip(n).take(m)を実行した場合、疑問に対する簡単な回答を提供しようとしています linqのメソッド(データベースサーバーとしてSQL 2005/2008を使用)では、クエリはSelect ROW_NUMBER() Over ...を使用します。 ステートメント、withは、SQLエンジンでの直接ページングです。

    例を挙げると、mtcityというデータベーステーブルがあります。 そして私は次のクエリを書きました(エンティティへのlinqでも同様に機能します):

    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がの実行プランを生成して保存できるようになるため、さらに優れたものになります。クエリ(パフォーマンスの向上)。



    1. SQLでリレーションシップを作成する

    2. 任意の列に「x」が含まれるSQLServerSELECT

    3. SQLのチューニング

    4. 複数のIPアドレスに対してpostgresqlpostgresql.conflisten_addressesを構成する方法