2009-11-02 164 views
2

我有一个DataView.Sort的性能瓶颈。代码如下。DataView.Sort是一个性能瓶颈

/// <summary> 
    /// Filters the data table and returns a new data table with only the filtered rows. 
    /// </summary> 
    /// <param name="dtInput">The dt input.</param> 
    /// <param name="filterExpression">The filter expression.</param> 
    /// <returns></returns> 
    protected virtual DataTable FilterDataTable(DataTable dtInput, string filterExpression) 
    { 
     DataTable result = dtInput; 
     if (!string.IsNullOrEmpty(filterExpression) && filterExpression.Trim().Length > 0) 
     { 
      DataView view = new DataView(dtInput); 
      view.RowFilter = filterExpression; 
      view.Sort = HierarchyFieldMap.DisplayedValue; 
      result = view.ToTable(); 
     } 
     return result; 
    } 

有关如何改进此方法的任何想法?

需要1秒钟才能执行。

编辑

我发现DataView's Poor Peformance with Large RecordSets

+0

你有几行? – 2009-11-02 23:53:49

+0

这取决于。 50到100k是可能的。 – 2009-11-02 23:57:46

回答

2

既然你不返回一个DataViewDataTable,你应该能够获得性能提升 - 没有订单的数量级,但25-30% - 通过使用DataTable.Sort

private static DataTable SortDataTable(DataTable t, 
    string filterExpression, 
    string sortExpression) 
{ 
    DataTable t1 = t.Clone(); 
    t1.BeginLoadData(); 
    foreach (DataRow r in t.Select(filterExpression, sortExpression)) 
    { 
     t1.Rows.Add(r.ItemArray); 
    } 
    t1.EndLoadData(); 

    return t1; 
} 

大部分时间都是将数据复制到新表中。如果你可以避免创建一个新表格并且使用DataTable.Select返回的DataRow的数组,你可以得到相当大的改进。

+0

没有理由创建一个新表。我被选择关闭了,因为它返回了一个DataRow []。我想它让我回到与DataView相同的船上,不得不将行复制到新的DataTable中。 – 2009-11-11 22:07:57

1

此链接可能更快数据库的所有索引和可用的统计信息进行排序,特别是如果你向用户显示之前分页的结果。

+0

我同意,但将其移至数据库目前不是一种选择。 – 2009-11-03 00:40:02

1

我同意Sheng的观点,当你必须对50-100k行进行排序时,是时候将一些逻辑移动到专门用于数据库的层上。创建一个存储过程,将rowlimit和当前页面作为参数,或者jsut根据这些值构建select语句,.NET很快,但并未针对这些操作进行优化,其中SQL server(或任何关于此的RDBMS )。

+0

虽然100%同意你的观点,但这不是一种选择。应用程序体系结构和时间线不适合将排序移动到数据库。 – 2009-11-03 00:39:23

+0

然后可能会将数据存储排序以一些通用列表的形式移动到较低级别,这些列表将数据保留为强类型对象而不是数据表/视图中的行,然后对其进行排序(使用LINQ也许),然后重新绑定网格(或者你代表数据)。 – Colin 2009-11-03 01:37:25