ASP.NET ViewState vs Session,大数据量
我有一个 WebUserControl,它从 SQL 获取记录并将其存储在 ViewState 中,到目前为止效果很好。但现在我有一个包含 100k+ 记录的数据集,我注意到在每次回发时,XHR 请求都会下载所有数据,并且速度非常慢,如果我将数据存储在会话中,则不会发生这种情况,所以我会问是否可以存储这么多数据在会话变量中?
我的测试:
- 视图状态: ViewState 网络响应
- 第一个请求读取数据并存储在 ViewState 中(时间: 11s,大小:119MB)
- 第二个请求是一个通用的回发,与视图状态无关,尽管如此,它需要很长时间才能收到回复并下载大量数据(时间: 15 秒,大小:119MB)
- 总计:26 秒,238MB
- 会话: 会话网络响应
- 第一个请求读取数据并存储在会话中(时间: 7s,大小:123kB)
- 第二个请求是一个通用回发,与会话无关,并且速度很快(时间:60ms,大小:122kB)
- 总计: 7s,244kB
经过这次测试,我的意思是,将数据存储在 Session 而不是 ViewState 中似乎要好得多,检索数据更快并且每个请求下载的数据更少,但是我'我不完全确定这是一个好的做法,也许有更好的方法可以做到这一点,但我忽略了。我希望这一点很清楚,英语不是我的母语,对此感到抱歉。
I have a WebUserControl that get Records from SQL and store inside a ViewState, this has worked fine so far. but now i have a DataSet with 100k+ records and i noticed that at each PostBack the XHR Request download all the data and is very slow, this not happen if i store data in Session, so i will ask is good to store this amount of data in a session variable?
My Test:
- Viewstate:
ViewState Network Response
- The first request read the data and store inside the ViewState (Time: 11s, Size: 119MB)
- The second request is a generic postback that do nothing with the viewstate, despite this, it takes a long time to receive a reply and downloads a lot of data (Time: 15s, Size: 119MB)
- Total: 26s, 238MB
- Session:
Session Network Response
- The first request read the data and store inside the Session (Time: 7s, Size: 123kB)
- The second request is a generic postback that do nothing with the Session and is fast (Time: 60ms, Size: 122kB)
- Total: 7s, 244kB
After this test, i mean, it would seem is a lot better to store data in Session instead of ViewState, is more fast to retrive data and download less data for each request, but i'm not totally sure is a good pratice, maybe there is e better method for do this that i ignore. i hope this is clear, English is not my first language sorry for that.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你说得很对。事实上,我什至发现整个页面大小可能超出 Web 配置中设置的回发限制。
然而,有两个重要的问题:
正如评论中指出的那样,用这么多数据加载 session() 也是一个非常糟糕的主意。
下一步:
你真的需要在 session() 中存储那么多数据吗?虽然您指出了性能的巨大提升,但您仍然给 Web 服务器带来了非常大的负载。这将耗尽 session() 内存,更糟糕的是,如果使用基于 sql server 的会话,那么您将在 sql server 上施加相当大的负载(该 blob 数据由 .net 序列化,然后保存到中的一行) sql server 会话状态 - 这又会在 sql server 上造成非常大的负载 - 即使“序列化”到会话中也需要一些时间)。
一个页面上真正可以显示多少行数据? 30顶?
现在,对于几千行,我什至不敢使用 ViewState。它只是过度加载和膨胀网页。
只需说 1000 行,以及网格视图(或列表视图)的数据分页,那么这就可以工作。
但是,超过 1000 行呢?
加载那 100k 行的距离甚至不近,而且在同一个星球上。这根本不可能。
想想谷歌,甚至任何其他软件——网络或桌面。
我们不会下载整个互联网,然后让你使用 ctrl-f 来搜索庞大的数据页面。
这也一样。
那么,这到底意味着什么呢?
您必须转储内置数据分页器,并编写自定义代码。
您可以在最新版本的 sql server(2012 年起)中使用所谓的 sql server 数据分页。因此,这意味着我们希望让 SQL Server 进行数据分页,而不是加载整个庞大的数据,然后尝试对该数据进行分页。尝试一次性处理如此大量的数据是不切实际的——至少从用户界面的角度来看是这样。
(无论如何,用户如何一次处理 100,000 行 - 这实际上是不可能的。
这意味着,如果您的页面有 30 行?那么您甚至不需要 ViewState 或会话。您只从 100,000 行中提取 30 行行,您的性能将在一秒内加载(和数据页)!
并且您减少了服务器上的大量内存使用,并且如上所述,减少了视图状态的大小(你只有 30 行——这样,你甚至可以让 gridview/list 视图继续使用视图状态(它们拥有的自动视图状态)。
所以,看看这个概念 。您仍然可以拼凑出看起来像数据分页器的东西,并且可以获取(计算)该表中的总行数,但您只能说一次提取 30 行。
sql 服务器端分页 这里:
在 SQL Server 中对结果进行分页的最佳方法是什么< /a>
如果您没有 sql server 2012 或更高版本,上面的链接和帖子概述了一些替代方法。我的观点和立场是,使用 2012 年更新的“分页”功能是一种简单的方法,尽管上面发布的一些解决方案被认为更快。
所以,你必须在这里建立一个寻呼机。您可以自己推出,但归根结底,内置分页系统实际上只是为了更好的 UI 性能,并且实际上只适用于大约 1000 行数据。之后,您需要采用分页系统,您的软件和用户会因此而喜欢您 - 因为一切都会响应并运行得与您单击鼠标一样快。您甚至不需要为此采用 ajax 调用,但您必须减少从 SQL Server 提取的行数 - 减少到 30 或 20 或网格一次显示的任意多行。
You are quite correct. In fact, I have even found that the whole page size can exceed the limits for post backs set in web config.
However, two significant issues:
Loading up session() with that much data is as pointed out in comments ALSO a very bad idea.
Next up:
Do you REALLY need to store that much data in the session()? While you pointed out the huge performance increase - you still putting a VERY large load on the web server. that is going to eat up session() memory, and worse if using sql server based sessions, then you going to put quite a hard load on sql server (that blob of data is serialized by .net, and THEN saved to ONE row in sql server session state - and that again is going to be very hard load on sql server - even time to "serialize" into session going to take some time).
And how many rows of data can you really display on a page? 30 tops?
Now, for a few 1000 rows, I even then would not DARE use ViewState. It simply loads up and bloats up the web page far too much.
And with only say 1000 rows, and data paging of the grid view (or list view), then this can work.
But, beyond 1000 rows?
Not even close and on the same planet are you to load that 100k of rows. It is simply out of the question.
Think of Google, or even any other software - web or desktop.
we don't download the WHOLE internet, and then say have you use ctrl-f to search the huge monster page of data.
Same goes for this.
So, what does this REALLY mean?
You have to dump the built in data pager, and write custom code.
You can with most recent versions of sql server (2012 onwards) can use what is called sql server data paging. So, this means we want to let SQL server do the data paging, and NOT LOAD the whole big elephant of data, and THEN attempt to page that data. It just not practical to try and deal with that amount of data in one shot - at least from a UI point of view.
(how can a user deal with 100,000 rows at one time anyway - it not really possible.
This means, that if you page has 30 rows? Well, then you not even need ViewState or session. You pull ONLY 30 rows out of the 100,000 rows, and your performance will be instant. Your pages will load (and data page) WELL UNDER one second of time!!!
And you cut down huge memory use on the server, and you also as noted, cut down the size on view state. (you only ever have say 30 rows - and with that, you even find to let the gridview/list view continue to use view state (the automatic view state that they have).
So, check out the concept of sql server side paging. You can still cobble together what looks like a data pager, and you can get (count) the total number of rows in that table, but you only ever say pull 30 rows at a time.
How this works is outlined here:
What is the best way to paginate results in SQL Server
And the above link and post outlines some alternative approaches if you don't have sql server 2012 or later. I am of the view and position that using the newer "paging" features of 2012 is the simple approach, despite that some solutions posted in above are noted to be even faster.
So, you have to build a pager here. You can roll your own, but at the end of the day, the built in paging system is REALLY only for better UI performance, and really only works for about 1000 rows of data. after that, you need to adopt a paging system, and your software and users will love you for this - since everything will respond and run quite much as fast as you can click the mouse. You don't even need to adopt ajax calls for this, but you do have to cut down the rows pulled from SQL server - down to 30 or 20 or however many rows your grid displays at one time.