新社区网站

通常,你会在正确的地方,但我们最近推出了一个全新的社区网站……为社区,受社区。

耶……带我去社区!

社区博客是社区成员的个人观点,绝不是DNN公司或DNN平台的官方立场。这是一个表达个人对DNNPlatform、社区及其生态系统的想法的地方。你有什么有用的信息想要与DNN社区分享吗?如果有,请联系

社区博客的使用由我们的社区博客指南-请在评论或发布之前阅读。


表单和列表-慢吗?

表单和列表,或者它的前身“用户定义表”模块,是为创建和维护列表而设计的。由于输出可以用模板控制,该模块可以用于许多不同的场景:公告、联系人列表、食谱、词汇表、常见问题解答、留言簿、评论、地址列表、地图等。简而言之,表单和列表是一个适用于许多不同用例的通用工具箱。

设计灵活性也有缺点;它没有针对性能进行优化。数据是动态的;列表不直接映射到SQL表。相反,数据被序列化成字段值对流,这使得很难直接用SQL处理。您不能使用简单的SQL语句进行查询,而且索引对搜索也没有好处。

对于很多用例,这种方法已经足够好了,通常列表很小,只包含几十到几百个条目。但我听说过更大的安排。他们通常开始小,设置是快速和容易。一开始一切都很顺利。然后,经过一段时间的生产后,数据增长到数千条记录,将体验变成一场噩梦。在论坛上被问到时,我们只能承认这是设计出来的。

我们过去使用较大的记录集进行了一些测试,并且能够解决最坏的减速影响。最后几天,我花了一些时间进行更严肃的测量。为了更好地理解,我将勾勒出表单和列表的渲染管道。

渲染过程


SQL模式

  1. Form和List中的每个单元格都存储在表“UserDefinedData”中。表中的每条记录都包含价值作为字符串并引用。将值保存到类型的列中ntext (*)
  2. 表“UserDefinedFields”保存着列表的模式。除了名称和字段类型之外,它还包含最常见的属性。此外,表“UserDefinedFieldSettings”根据当前字段类型保存了额外的专门化信息。
  3. 所有模块实例的数据通过调用存储过程并将内容加载到具有三个datatable的数据集中来传输:字段FieldSettings,数据
  4. 在加载时,字段值对流被传输并旋转到DataTable中数据。它的列映射到字段,并且值已经转换为匹配的系统数据类型,如String或Int。
  5. 一些表单和列表类型需要特殊处理:
    1. 例如,datetime值存储在UTC中,尽管它们应该在门户或用户时间中显示。我们也不想为布尔值显示一个简单的0或1,而是显示一个复选框的图像,是否选中取决于该值。
    2. 某些类型返回对页面/制表符或文件的引用,例如:文件标识= 1234。诸如名称、路径或下载URL之类的信息需要通过额外的API调用来检索。
    3. 其他类型(如计算列)则动态执行,查询其他列
    4. 表单和列表添加隐藏列以获取收集到的任何其他信息。
  6. 创建完所有列后,就可以创建数据表了排序过滤后的对着任何柱子。这是旧时尚数据集的一个好处;早在Linq (to object)之前,它就支持脱机过滤语句。
  7. 作为最后一步,将数据集(最好是表数据)绑定到网格上,或者将数据集转换为XML和xsl——转换为Html。

简而言之:
GetData模块→创建数据集→丰富数据集→过滤数据集->绑定到输出

可能有多少记录?

它是如何表现的呢?首先,让我们从一个数据类型为text的自定义字段开始,用字符串“text”填充。由/at创建/更改的强制审计字段也是该模块的一部分。我只是将每次访问的记录数量增加了10倍。结果如下:

x轴表示记录的数量,y轴表示所需的时间。

呈现时间尺度与记录的数量成线性关系。在我的机器上渲染10,000条记录需要大约两秒钟的时间。这对于只有视图访问者的小型网站来说可能是可以接受的,但在繁忙的环境中肯定会造成麻烦。

电场类型的影响

接下来,我创建了一个列表,其中包含每种数据类型的一个字段。我添加了几行代码,导出了一个模块,编辑了多次复制数据部分的XML,然后再次导入。这产生了一个大约有18000条记录的列表。从页面加载到输出需要超过35秒的时间。现在我对渲染管道的不同部分的影响很感兴趣:

正如您所看到的,将这个集合从数据库加载到数据表已经花费了将近5秒的时间,但是大部分时间都花在了字段的处理上(5)。让我们详细分析一下:

(请注意,y轴是exp10

  • 时间简单类型(字符串和数字)可以被安全地忽略。我们说的是纳秒。
  • 值类型添加隐藏列(5)耗时约10µs。如果编写时没有考虑到性能,即使重复调用本地化也会导致延迟。
  • 引用类型(5b)正在调用API来检索更多信息,在最坏的情况下导致额外的缓慢的数据库调用。下载已经花费了0.1ms。Image类型甚至更慢,但已经优化(**)设置。
  • 计算列而查找也不是那么慢,至少对于非常简单的表达式来说是这样。
  • 加载数据需要时间,并且与第一次记录的尺寸相匹配。
  • 绑定到数据网格或XSL转换(不在本记录中)可以忽略,至少如果它们限制了输出的数量,例如使用分页。

结果

  • 表单和列表在每个模块的记录数量有限的情况下工作得非常好,支持并解决了许多用例。它从来就不是为更大的数据集设计的。
  • 关于什么是合理的大小,没有一个通用的答案——它在很大程度上取决于不同数据类型的使用情况。
  • 如果您将超过1,000条记录存储到单个Form和List中,并且该列表仍在增长,则可能需要重新考虑您的设计。

结论

我希望这个考试能帮助你优化你的表单和列表处理。问题是,这是否也有助于优化模块本身。我过去有过很多关于绩效的建议,这里有一些想法和我的观点:

  • 虽然System.Data.DataSet速度较慢,但它仍然是模块的基础。如果它被任何illist替换 和Linq,它肯定会提高速度,但任何过滤器或计算列肯定会被打破。它将不再是表单和列表。
  • 数字或bool字段的类型感知列将没有可测量的效果,因为这些改进将发生在ns的维度上,而不是µs。
  • 缓存很困难,因为数据集可能对当前上下文有很多依赖,例如用户时间、本地化或令牌
  • 优化某些类型是可能的,因为API调用的结果可以缓存,至少每个请求(**)。
  • 在数据库内部连接以填充关于选项卡和文件的信息对于性能来说是有意义的,但是它会绕过公共DotNetNuke API。DotNetNuke架构不是API的一部分,可以在每个新版本中进行更改——这甚至不是一个bug,只是糟糕的编程。此外,Form和List数据类型独立于模块。可以删除、替换或添加新的数据类型到Form和List,而无需触及模块的源代码。

当前方法的缺点是,过滤发生在渲染管道的非常后期的状态。因此,可以针对任何列和列类型进行筛选和排序。

解决方案可能很简单,通过在SQL服务器端添加过滤:
在SQL Server上过滤数据→为模块GetData→创建数据集→丰富数据集→过滤数据集→绑定输出

这里我不喜欢的是它不能对每种数据类型都起作用,过滤在管道中会发生两次,两种类型的过滤器肯定会有不同的语法。没有任何背景知识的用户会感到困惑。

我想知道你在想什么。表单和列表是否提供任何额外的过滤器支持?还有其他想法吗?

*将字段值的类型从ntext更改为nvarchar(max)不会对性能产生任何影响,尽管它在其他原因上是有意义的。
**在这里的特殊情况下,只有大约20个不同的图像一次又一次地重复,缓存将图像的时间从大约12秒减少到不到一秒(18k记录)。

评论

评论形式

只有注册用户才能发表评论。

NewsArchives


Aderson Oliveira(22岁)
亚历克·惠廷顿(11岁)
亚历山德拉·戴维斯(3岁)
Alex Shirley(10岁)
安德鲁·霍夫林(3岁)
安德鲁·纳斯(30岁)
安迪·特里巴(1)
安东尼·格伦赖特(5岁)
安东尼奥·夏格里(28岁)
阿什·普拉萨德(37岁)
本·施密特(1)
本杰明·赫尔曼(25岁)
伯努瓦·萨顿(9岁)
贝丝·费尔堡(12岁)
比尔·沃克(36岁)
鲍勃·克鲁格(5岁)
波格丹·莱特斯库(1)
布莱恩·杜克斯(2岁)
白雪皑皑(1)
布鲁斯·查普曼(20岁)
布莱恩·安德鲁斯(1)
卡塔·康诺利(55岁)
查尔斯·纳斯(163)
克里斯·哈蒙德(第213届)
克里斯·帕特拉(55岁)
克林特·帕特森(108)
邝党(21岁)
丹尼尔·巴塞洛缪(2岁)
丹尼尔·梅特勒(181)
丹尼尔·瓦拉达斯(48岁)
戴夫·巴克纳(2岁)
大卫·波因德克斯特(12岁)
大卫·罗德里格斯(3岁)
萧耀文(1)
道格·豪厄尔(11岁)
Erik van Ballegoij(30岁)
恩斯特·彼得·塔明加(80岁)
弗朗西斯科·佩雷斯·安德烈斯(17岁)
杰夫·巴洛(12岁)
乔治·阿拉特拉什(12岁)
吉福德·沃特金斯(3)
吉尔·勒·皮戈彻(3)
伊恩·罗宾逊(7岁)
以色列·马丁内斯(17岁)
简·布洛姆奎斯特(2)
简·乔纳斯(3岁)
贾斯普雷特·巴蒂亚(1)
詹妮·梅里菲尔德(6岁)
乔·布林克曼(274)
约翰·米切尔(1)
乔恩·亨宁(14岁)
乔纳森·希利(4岁)
乔丹·库珀史密斯(1)
约瑟夫·克雷格(2岁)
马侃(1)
凯文贝吉(3岁)
凯利·福特(4岁)
肯·格里尔森(10岁)
凯文·施莱纳(6岁)
利·波因特(31岁)
洛林·杨(60岁)
Malik Khan (1)
马特·拉特利奇(2岁)
马蒂亚斯·施洛曼(16岁)
毛里西奥Márquez (5)
迈克尔·多克西(7岁)
迈克尔·托比什(3岁)
迈克尔·华盛顿(2002)
米格尔·加梅坦(3)
迈克·霍顿(19岁)
米歇尔·塞勒斯(40岁)
弥敦罗孚(3)
Navin V Nagiah(14岁)
n (31)
Nik Kalyani(14岁)
奥利弗·海因(1)
帕特里西奥·f·萨利纳斯(1)
帕特里克·瑞恩(1)
彼得·唐克(54岁)
菲利普·比德尔(135岁)
菲利普·贝克尔(4岁)
理查德·杜马斯(22岁)
罗伯特·J·柯林斯(5岁)
罗杰·塞尔温(8岁)
鲁本·洛佩兹(1)
莱恩·马丁内斯(1岁)
Sacha Trauwaen (1)
爱沙尼亚语(4)
Sanjay Mehrotra(9岁)
斯科特·麦卡洛克(1)
斯科特·施莱西尔(11岁)
斯科特·威尔金森(3岁)
斯科特·威尔海特(97岁)
塞巴斯蒂安·洛波德(80岁)
肖恩·沃克(237)
肖恩·梅哈菲(17岁)
斯蒂芬·卡尔曼(12岁)
Stefan Kamphuis(12岁)
史蒂夫·法比安(31岁)
史蒂文·费舍尔(1)
蒂莫·布鲁梅尔霍夫(24岁)
托尼·亨利克(3岁)
托斯滕·韦根(3岁)
第谷·德·沃德(4)
Vicenç Masanas(27岁)
Vincent Nguyen(3岁)
维塔利·科扎达耶夫(6岁)
威尔·摩根维克(40岁)
威尔·斯特罗尔(180岁)
威廉·塞弗伦斯(5岁)
什么是液体含量?
找出
什么是液体含量?
找出
什么是液体含量?
找出
Baidu
map