ADO.Net DataTables有索引吗?

我正在使用VSTS 2008 + C#+ .Net 3.5 + SQL Server 2008 + ADO.Net。 如果我使用ADO.Net的DataTable从数据库加载表,并在数据库表中,我在表上定义了几个索引。 我的问题是,是否在ADO.Net DataTable上,有相关索引(与我在物理数据库表上创建的索引相同)来提高DataTable的某些操作性能?

乔治,提前谢谢

乔治,

答案是不。

实际上,某种索引可以在内部使用,但仅作为实现细节。 例如,如果您创建外键约束,可能是由索引辅助。 但这对开发人员来说无关紧要。

实际上乔治的问题并不像有些人坚持的那样“糟糕”。 (我越来越相信没有这样的想法是“一个坏问题”。)

我有一个相当大的表,我加载到DataTable对象的内存中。 很多时候,在这个表的行上进行了很多处理,在各种(和不同的)子集上,我可以很容易地将其描述为SELECT子句的“WHERE …”。 现在有了这个DataTable,我可以运行Select() – 一个DataTable类的方法 – 但效率很低。

最后,我决定加载按特定列排序的DataTable并实现我自己的快速搜索,而不是使用Select()函数。 它被certificate要快得多,但当然它只适用于那些排序的列。 如果DataTable有索引,就可以避免麻烦。

不,但可能是的。

您可以使用DataView在DataTable上设置自己的索引。 当您更改表时,将重建DataView,因此索引应始终是最新的。

我为自己的应用做了一些基准测试。 我使用DataTable来逼近Boost MultiIndexContainer。 要在列调用“Author”上创建索引,我初始化DataTable,然后是DataView …

_dvChangesByAuthor = new DataView( _dtChanges, string.Empty, "Author ASC", DataViewRowState.CurrentRows); 

然后,要从表中按作者提取数据,使用视图的FindRows函数…

  dataRowViews = _dvChangesByAuthor.FindRows(author); List returnRows = new List(); foreach (DataRowView drv in dataRowViews) { returnRows.Add(drv.Row); } 

我做了一个随机的大型DataTable,并使用DataTable.Select(),Linq-To-DataSet(通过导出到列表强制执行)和上面的DataView方法运行查询。 DataView方法很容易获胜。 Linq拿了5000个滴答,Select拿了26000个滴答,DataView拿了192个滴答…

 LOC=20141121-14:46:32.863,UTC=20141121-14:46:32.863,DELTA=72718,THR=9,DEBUG,LOG=Program,volumeTest() - Running queries for author >TFYN_AUTHOR_047< LOC=20141121-14:46:32.863,UTC=20141121-14:46:32.863,DELTA=72718,THR=9,DEBUG,LOG=RightsChangeTracker,GetChangesByAuthorUsingLinqToDataset() - Query elapsed time: 2 ms, 4934 ticks; Rows=65 LOC=20141121-14:46:32.879,UTC=20141121-14:46:32.879,DELTA=72733,THR=9,DEBUG,LOG=RightsChangeTracker,GetChangesByAuthorUsingSelect() - Query elapsed time: 11 ms, 26575 ticks; Rows=65 LOC=20141121-14:46:32.879,UTC=20141121-14:46:32.879,DELTA=72733,THR=9,DEBUG,LOG=RightsChangeTracker,GetChangesByAuthorUsingDataview() - Query elapsed time: 0 ms, 192 ticks; Rows=65 

所以,如果你想在DataTable上使用索引,我会建议使用DataView,如果你能处理在数据发生变化时重建索引的事实。

您可以为数据表创建主键。 如果您在主键字段中搜索,则过滤操作会得到很大的提升。 看看这个链接: 这里

上面的约翰是对的。 DataTables在内存结构中断开连接。 它们不映射到数据库的物理实现。

磁盘上的索引用于加速查找,因为您没有所有行。 如果你必须加载每一行并扫描它们很慢,那么索引是有意义的。 在DataTable中,您已经拥有了所有行,因此比较速度已经很快。

我对来自大数据表的许多查询存在同样的问题,这些查询不是根据主键。

我找到的解决方案是为我想要使用的每个索引创建DataView,然后使用它的Find和FindRows方法来提取数据。

DataView在DataTable上创建一个内部索引,并且几乎可以作为索引用于此目的。

在我的情况下,我能够将10,000个查询从40秒减少到1秒!

其他人已经指出DataSet不是用作数据库系统 – 只是数据的表示。 如果您的工作印象是DataSet是一个数据库,那么您就错了,可能需要重新考虑您的实现。

如果您需要客户端数据库,请考虑使用SQL Compact或SQL Lite,两者都是可免费再发行的数据库系统,无需单独的安装或服务即可使用。 如果您需要更全面的function,SQL Express将是下一步。

为了帮助澄清,在.NET开发中使用DataSet / Tables来根据需要临时保存数据。 将它们视为针对数据库的SELECT查询的结果; 它们大致类似于CSV文件或其他forms的表格数据 – 您可以从数据库中将数据提取到数据库中,处理数据,然后将更改推送回数据库 – 但它们本身并不是数据库。

如果由于某种原因需要保留在内存中的大量项目,那么您可以考虑构建轻量级DTO(数据传输对象,Google,它们非常简单)并将它们加载到HashTable中。 HashTables不会为您提供任何forms的关系数据,但在查找时非常有效。

DataTables有一个可以作为索引的PrimaryKey字段(无论如何它们都很快)。 此字段不会从数据库的主键复制(尽管这可能很好)。

如果您(编码人员)将一个或多个DataColumns指定为主键,则会为DataTable编制索引。 在整体上,ADO.NET使用红黑树形成此索引,从而提供日志时间查找。 不会根据数据提供程序的任何基础键控自动设置此主键。

这里正确的答案是从DataTable创建一个DataView,根据doc将创建一个索引:

DataView构造索引。 索引包含从表或视图中的一个或多个列构建的键。 这些键存储在一个结构中,使DataView能够快速有效地查找与键值关联的行。 使用索引的操作(例如筛选和排序)会显着提高性能。 DataView的索引是在创建DataView时以及修改任何排序或过滤信息时构建的。 创建DataView,然后设置排序或过滤信息会导致索引至少构建两次:一次创建DataView时,再次修改任何sort或filter属性。

我对文档的阅读是,实现这一目标的正确方法(如果需要)是使用AsDataView生成绑定到基础表的DataView (或LinqDataView )。 如果您的DataTable是不变的,那么DataView可以是静态的,以避免冗余的重新索引。

我目前正在调查Linq to DataSet ,这个q对我有帮助,谢谢。