我需要在一个网页上获取和显示数据,这些数据的记录数可能会因为筛选器而变化,从大约500个记录到100万个记录不等。
由于将百万条记录存入内存并不明智,所以缓存是否有用呢?SqldataReader
?
当然必须实现分页。显示100万条记录是最坏的情况(使用场景中愚蠢的All filter
!)。
我应该使用连接架构(SqlDataReader)还是离线架构(DataSets)?
我需要在一个网页上获取和显示数据,这些数据的记录数可能会因为筛选器而变化,从大约500个记录到100万个记录不等。
由于将百万条记录存入内存并不明智,所以缓存是否有用呢?SqldataReader
?
当然必须实现分页。显示100万条记录是最坏的情况(使用场景中愚蠢的All filter
!)。
我应该使用连接架构(SqlDataReader)还是离线架构(DataSets)?
首先,要这样考虑:向用户展示一百万条记录对任何用户都没有意义。因此,你必须考虑用户想要看到什么。也许是摘要?!也许将记录分页,每页显示25、50或100条记录。这些方法之一都不需要在内存中同时保存1M条记录。
此外,当你针对 SQL 数据库运行查询并使用 SqlDataReader 时,你将不会收到所有记录,而是 SQL 驱动程序将查询发送到 SQL 服务器,服务器将执行查询,准备一个结果集并创建一个仅可向前的游标。然后驱动程序将每次在你的 SqlDataReader 上调用Read()时抓取一条记录。如果你使用延迟执行的 LINQ to SQL,行为非常类似。结果集直到(或除非)你明确请求每一行才会全部传输过来。
因此,简单的分页查询就能搞定了。或者在其他情况下,可以生成某种汇总报告,从这1百万条记录中聚合数据并显示一两页相关数据。
当然,如果您需要在页面之间来回浏览,可能需要某种缓存,但再次考虑一下:用户有多经常需要浏览1百万条记录 - 可能永远不需要。
最后,请确保你使用的分页方法依赖于 SQL 服务器一次只发送一页数据,而不是将所有1百万条记录读入 ASP.NET 中,然后对本地副本的数据进行分页,因为那将非常低效和缓慢。这里有一个执行分页的 SQL Server 查询示例:SO Question #109232
我同意其他回答者的观点。展示1M条记录是荒谬的。但是,您可以显示前X条记录,并进行分页。
关键在于执行提取数据的存储过程中。
ALTER PROCEDURE [dbo].[MyHugeTable_GetWithPaging]
(
@StartRowIndex int,
@MaximumRows int
)
AS
SET NOCOUNT ON
Select
RowNum,
[UserName]
From
(Select
[ID],
[UserName]
Row_Number() Over(Order By [ID] Desc) As RowNum
From dbo.[MyHugeTable] t)
As DerivedTableName
Where RowNum Between @StartRowIndex And (@StartRowIndex + @MaximumRows)
Create proc Test
@take smallint,
@skip smallint,
@orderBy nvarchar(20),
@subscriptionid smallint,
as
DECLARE @SQLQuery AS NVARCHAR(max)
SET @SQLQuery=' Select ROW_NUMBER() OVER (ORDER BY P.ProductId desc) as RowNum,* from product"
set @SQLQuery=@SQLQuery + ' and Subscriptionid='+CONVERT(nvarchar, @subscriptionid)
set @SQLQuery= ';WITH Results_CTE AS ( '+@SQLQuery
set @SQLQuery= @SQLQuery +' ) SELECT * FROM Results_CTE WHERE RowNum > '+CONVERT(nvarchar, @skip)+' AND RowNum <= '+CONVERT(nvarchar, @skip+@take) --//paging';
END
EXECUTE sp_executesql @SQLQuery