对计算字段进行排序和过滤

Posted

技术标签:

【中文标题】对计算字段进行排序和过滤【英文标题】:Sorting and Filtering on a Calculated Field 【发布时间】:2018-09-22 17:51:21 【问题描述】:

我目前正在使用NonFactors/MVC6-Grid 来表示我的索引页面上的数据,这是一个使用 .NET Core 2.0 和 MVC 构建的相当基本的 CRUD 应用程序。我有一个包含多个字段的模型,其中一些是计算字段。

使用 MVC 网格进行排序和过滤非常有效,即使记录超过 550,000 条。但是,当我尝试对其中一个计算字段进行排序和过滤时,性能会大大降低(大约需要 45 秒)。这不是世界末日,但我想知道是否有办法提高计算字段的性能?

我很确定性能下降要么是由于计算字段上缺少索引,要么是因为每个记录的计算属性都被重新计算并然后排序/过滤,或两者兼而有之。

如果有人对瓶颈可能在哪里有任何见解,并且如果有办法可以提高性能,我们将不胜感激。

【问题讨论】:

不清楚“计算字段”是什么意思。这是映射到数据库表中计算列的属性吗?或者只是一个 get only 属性从对象的其他属性进行一些计算?因为在第二种情况下,EFC 只是从数据库中检索整个表数据并在客户端执行过滤/排序,这应该可以解释为什么它这么慢。 @IvanStoev 抱歉,不清楚。我说的是根据对象上的其他属性计算的属性。我相信我会尝试为所需的计算实现服务器端/持久列 然后避开那个属性,尝试使用对应的表达式。否则 EF Core 将使用客户端评估。这对于排序可能没什么大不了的(除非您还进行分页),但对于过滤而言,这将是一个真正的瓶颈。 【参考方案1】:

来自 SQL 文档

计算列不能用作 DEFAULT 或 FOREIGN KEY 约束定义或使用 NOT NULL 约束定义。 但是,如果计算的列值由确定性定义 表达式和结果的数据类型允许在索引中 列,计算列可以用作索引中的键列或 作为任何 PRIMARY KEY 或 UNIQUE 约束的一部分。例如,如果 表有整数列 a 和 b,计算列 a + b 可能是 索引,但计算列 a + DATEPART(dd, GETDATE()) 不能 索引,因为该值可能会在后续调用中发生变化。

所以你也许可以设置一个索引...取决于计算。

还取决于您使用的 SQL Server 版本....您可以将该列标记为 PERSISTED。

使用索引在 SQL Server 上进行排序和过滤将比之前建议的客户端快得多

【讨论】:

谢谢,我不知道这存在。所需的计算相对简单,所以应该可以。【参考方案2】:

您从数据库中获取记录,根据条件过滤并在 C# 代码中进行计算,然后将其映射到您的 Dto 列表并应用排序。最后,将 Dto 列表返回给客户端代码。

【讨论】:

以上是关于对计算字段进行排序和过滤的主要内容,如果未能解决你的问题,请参考以下文章

通过相关模型上的过滤器对 list_display 字段进行排序

无法在 Drupal 7 的视图中对自定义字段进行排序或过滤

tableau可视化数据分析60讲-排序和过滤器

如何在ListAPIView中使用django-filter对过滤结果进行排序

django中的过滤顺序

使用 solr 中的函数进行过滤和排序