我需要在网页上获取和显示数据,其记录数量可能因大约500条记录到100万条记录的过滤器而异。
缓存在这里有用,因为我认为记忆中的百万记录不是一个好主意。 SqldataReader
?
当然,分页是必须实现的。显示100万条记录是最糟糕的情况(使用案例中的愚蠢All filter
。)。
我应该使用连接架构(SqlDataReader)还是断开连接的架构(DataSet)?
答案 0 :(得分:11)
首先,想一想:显示100万条记录对任何用户都没有意义。因此,您必须考虑用户期望看到的内容。也许总结一下?!也许可以将这些记录分页为25或50或100条记录。这些方法中的任何一种都不需要您在内存中一次保存1 M条记录。
此外,当您对SQL数据库运行查询并使用SqlDataReader时,您将不会收到所有记录,而是SQL驱动程序将查询发送到SQL服务器,服务器将执行查询,准备结果在服务器上设置并创建只进游标。然后,每次在SqlDataReader上调用Read()时,驱动程序将一次获取一条记录。如果使用使用延迟执行的LINQ to SQL,则行为非常相似。结果集不会被完全转移,直到(或除非)您具体请求每一行。
因此,一个简单的分页查询就可以了。或者在其他情况下,某种汇总报告汇总来自这100万条记录的数据,一页或两页相关数据。
当然,如果你确实需要在页面中来回移动,那么某种缓存可能会有意义,但请再想一想:用户实际想要浏览100万条记录的频率 - 可能永远不会。 / p>
作为最后一点,如果你实现了分页 - 请确保用于实现分页的方法依赖于SQL Server一次发送一页数据而不是将所有100万条记录读入ASP.NET然后对数据的本地副本进行分页,因为这样效率很低且速度很慢。以下是执行分页的SQL Server查询示例:SO Question #109232
答案 1 :(得分:3)
我同意其他的回答者。显示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)
答案 2 :(得分:1)
如果您的服务器无法缓存100万条记录,您认为您的用户的网络浏览器将如何处理100万条记录的HTML记录呢?
考虑分页(here is an example with 1 million records)
还要考虑用户永远不会想要超过30到50条记录。您要么显示的细节太低,要么需要更多过滤。
答案 3 :(得分:0)
我建议使用动态查询和分页。因此,当您单击特定页面时,仅为这些页面提取记录。要从特定范围从数据库中获取记录,请使用以下查询。
像这样。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