C# SQL 2005最佳“分页”

C# SQL 2005最佳“分页”,c#,.net,sql,sql-server-2005,C#,.net,Sql,Sql Server 2005,在使用自定义分页创建记录网格时,使用C查询记录总数以及记录开始和结束的最佳方法是什么 返回分页记录集的SQL: SELECT Some, Columns, Here FROM ( SELECT ROW_NUMBER() OVER (ORDER BY Column ASC) AS RowId, * FROM Records WHERE (...) ) AS tbl WHERE ((RowId > @Offset) AND (RowId

在使用自定义分页创建记录网格时,使用C查询记录总数以及记录开始和结束的最佳方法是什么

返回分页记录集的SQL:

SELECT Some, Columns, Here FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY Column ASC) AS RowId, *
    FROM
        Records
    WHERE
        (...)
) AS tbl
WHERE ((RowId > @Offset) AND (RowId <= (@Offset + @PageSize)) )
现在,我对服务器进行了两次访问:一次用于获取记录,另一次用于计算记录总数


组合这些查询以避免多次数据库跳闸的最佳方法是什么?

一种方法是将查询转换为存储过程,然后使用一个输出参数来计算总记录。您可以在过程中填充输出参数,然后以与现在相同的方式返回记录集。

您可以使用存储过程和输出参数或返回值来传递总行数

create procedure dbo.Stuff_GetAll (
    @StartRowIndex int, -- zero based
    @MaximumRows int
)
as
begin
    declare @TotalRows int

    select @TotalRows = count(*) 
    ...

    if (@TotalRows > 0 and @MaximumRows > 0)
    begin
        ;with T as (
            select *, row_number() over ()
            ...
        )
        select T.* from T
        where Row between @StartRowIndex + 1 and (@StartRowIndex + @MaximumRows)
    end

    return @TotalRows
end
GO

您可能希望仅在请求第一页时才在查询计数中添加检查,这可能非常昂贵。

我找到的最快方法是返回结果集中的行数:

With PagedItems As
    (
    Select ...
        , ROW_NUMBER() OVER ( ORDER BY Column ASC ) As Seq
        , ROW_NUMBER() OVER ( ORDER BY Column DESC ) As ReverseSeq
    From Table
    Where ....
    )
Select ..., ( ReverseSeq + Seq - 1) As TotalRows
From PagedItems
Where RowId > @Offeset
    ANd RowId <= ( @Offset + @PageSize )

就我个人而言,我讨厌使用SPs。他们一直是我的噩梦。在不创建SP的情况下,是否仍可以执行此操作?是的,您可以使用union将两个查询合并为一个查询,但这将需要动态查询构造,即使我讨厌SPs,但这对我来说太复杂了:。我在选择两个表后考虑使用NextResult。但我不知道如何在C语言中实现这一点。有趣的是,我从未听说过用;在单个查询中。这里有一个伪代码,目前无法测试,对不起:string query=select pageddata;选择计数*。。。var command=newsqlcommandquery,conn;IDataReader reader=command.ExecuteReader;while reader.Read//process row reader.NextResult;//如果reader.Read long totalRows=longreader[0],则转至计数结果;根据我的经验,此解决方案的性能可能很差,因为您必须执行同一查询两次。也就是说,为了填充@TotalRows,您必须执行原始查询,例如From子句、Where、cause等两次,一次用于Count*,一次用于CTE,在CTE中获得分页结果。如果查询非常复杂和/或如果您有大量数据,这将无法很好地执行。事实并非如此。虽然看起来非常优雅,但即使您有一个用于ASC排序的索引,实际上DESC的速度要慢得多。此外,结果集需要在返回的每一行中携带相同的信息。@UserControl-不这样认为。系统将对行进行单次传递。在我的测试中,它明显比临时表或带有count*@UserControl的子查询快——此外,对于每一行返回,计数作为列的返回是微不足道的。请记住,我们最多只能返回行中的@PageSize,因此每行增加4个字节对性能没有影响。我敢打赌SQL Server 2005可以保证ASC和DESC排序查询的速度相同,特别是当列上有单个索引时。例如,在现实中,您甚至常常没有一个索引,用于在网格中按自由用户可选择的列排序。事实上,排序与主题无关,只是排名函数需要排序,但不能同时使用ASC和DESC!确保我们有一致的结果集。
With PagedItems As
    (
    Select ...
        , ROW_NUMBER() OVER ( ORDER BY Column ASC ) As Seq
        , ROW_NUMBER() OVER ( ORDER BY Column DESC ) As ReverseSeq
    From Table
    Where ....
    )
Select ..., ( ReverseSeq + Seq - 1) As TotalRows
From PagedItems
Where RowId > @Offeset
    ANd RowId <= ( @Offset + @PageSize )