ADO.Net DataTables有索引吗?

Geo*_*ge2 18 .net c# sql-server datatable ado.net

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

乔治,提前谢谢

小智 19

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

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

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

  • @JohnSaunders将DataTable加载到内存中以用于大量查找似乎不是"很少开发人员"需要做的事情.鉴于数据库驱动的应用程序的范围,它似乎是一个相当普遍的事情.这就是微软实现[创建索引的DataViews]的原因(https://msdn.microsoft.com/en-us/library/bb669089(v = vs.110).aspx). (5认同)

Ste*_*ert 9

不,但可能是的.

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

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

_dvChangesByAuthor = 
    new DataView(
        _dtChanges, 
        string.Empty, 
        "Author ASC", 
        DataViewRowState.CurrentRows);
Run Code Online (Sandbox Code Playgroud)

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

            dataRowViews = _dvChangesByAuthor.FindRows(author);
            List<DataRow> returnRows = new List<DataRow>();
            foreach (DataRowView drv in dataRowViews)
            {
                returnRows.Add(drv.Row);
            }
Run Code Online (Sandbox Code Playgroud)

我做了一个随机的大型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
Run Code Online (Sandbox Code Playgroud)

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


小智 7

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


Noa*_*oam 6

我对来自大型数据表的许多查询都遇到了同样的问题,这些查询不是根据主键。

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

DataView 在 DataTable 上创建一个内部索引,并为此目的实际上充当一个索引。

就我而言,我能够将 10,000 次查询从 40 秒减少到 1 秒!!!


Joh*_*ers -2

乔治,

答案是不。

实际上,某种索引可以在内部使用,但仅作为实现细节。例如,如果您创建外键约束,则可能需要索引的帮助。但这对开发者来说并不重要。