考虑以下代码:
Dataview someView = new DataView(sometable)
someView.RowFilter = someFilter;
if(someView.count > 0) { …. }
有很多文章说Datatable.Select()比使用DataViews更好,但这些文章优于VS2008。
Solved: The Mystery of DataView's Poor Performance with Large Recordsets
Array of DataRecord vs. DataView: A Dramatic Difference in Performance
在这个主题上搜索我发现一些文章/论坛主题提到Datatable.Select()本身是非常错误的(不确定)并且在各种情况下表现不佳。
关于msdn上的这个(Best Practices ADO.NET)主题,建议如果在数据表上定义了主键,则应使用findrows()或find()方法,并使用Datatable.Select()。
本文here(.NET 1.1)对这三种方法进行了基准测试,并对其他方法进行了测试。但是这是针对1.1版的,所以不确定这些是否仍然有效。对此DataRowCollection.Find()的执行优于所有方法,Datatable.Select()优于DataView.RowFilter。
所以我对在数据表中查找行的最佳方法感到困惑。或者没有一种好方法可以做到这一点,根据场景存在多种解决方案?
答案 0 :(得分:52)
您正在寻找“在数据表中查找行的最佳方法”,因此我首先要问:“最佳”是什么?我认为,任何技术都有可能比其他技术更适合的场景。
首先,让我们看一下DataView.RowFilter
:DataView在数据绑定方面有一些优势。它非常面向视图,因此它具有强大的排序,过滤或搜索功能,但会产生一些开销,并且没有针对性能进行优化。我会为较小的记录集选择DataView.RowFilter
和/或利用其他功能(例如,直接数据绑定到视图)。
有关DataView的大部分事实,您可以在较旧的帖子中阅读,仍然适用。
其次,如果您只需要一次点击,则应该优先DataTable.Rows.Find
而不是DataTable.Select
。为什么? DataTable.Rows.Find只返回一行。实质上,当您指定主键时,会创建二叉树。这有一些与之相关的开销,但极大地加快了检索速度。
DataTable.Select
速度较慢,但如果您有多个条件并且不关心索引或未索引的行,则可以非常方便:它基本上可以找到所有内容,但未针对性能进行优化。从本质上讲,DataTable.Select必须遍历整个表格,并将每条记录与您传入的条件进行比较。
我希望你能发现这个小概述很有帮助。
我建议您查看 this article ,这对我的表现问题很有帮助。这篇文章包含一些引用。
稍微更新: 顺便说一下,这似乎有点超出了你的问题的范围,但它几乎总是最快的解决方案,在后端进行过滤和搜索。如果您想要简单并且在客户端上有 SQL Server 作为后端和.NET3 +,请转到LINQ-to-SQL。搜索Linq对象非常舒适,并创建在服务器端执行的查询。虽然LINQ-to-Objects也是一种非常舒适但速度较慢的技术。万一你不知道......
答案 1 :(得分:24)
Thomashaid的帖子总结得很好:
DataView.RowFilter
用于绑定。DataTable.Rows.Find
仅供主键 搜索。DataTable.Select
用于按多列进行搜索,也可用于指定订单。避免在循环中创建许多DataView并使用其RowFilters搜索记录。这将大大降低性能。
我想补充说DataTable.Select
可以利用索引。您可以通过创建DataView并指定排序顺序在DataTable上创建索引:
DataView dv = new DataView(dt);
dv.Sort = "Col1, Col2";
然后,当您调用DataTable.Select()
时,它可以在运行查询时使用此索引。我们已经使用这种技术在我们多次使用相同查询的地方认真提高性能。 (请注意,这是在Linq存在之前。)
诀窍是为Select
语句正确定义排序顺序。因此,如果您的查询是“Col1 = 1和Col2 = 4”,那么您将需要“Col1,Col2”,如上例所示。
请注意,索引创建可能取决于创建DataView的实际调用。我们必须使用new DataView(DataTable dt)
构造函数,然后在单独的步骤中指定Sort属性。对于不同的.NET版本,行为可能会略有不同。