3

使用多个匹配规则进行基于名称的查找可能比使用整数索引的查找要慢一些,这是有道理的。但是,当我们谈论数据集中平均 10-15 个 [column] 条目时,我很难相信这可以解释每行 3%(或在我的项目中为 5-7%)的相对成本. 在前面的陈述中值得澄清的是,我指的是发生这种“取消引用”的列数,而不是数据集中的记录数。上述这些成本是在这些查找每行发生一次的情况下进行的。所以它们可能会发生很多。

idr.GetOrdinal(name) // Name based lookup
idr[name]  // Name-based lookup
idr.GetValue(index) // Ordinal-based lookup

实际上是否需要与数据库进行额外的通信来进行基于名称的字段查找?是什么让他们这么慢?

我还注意到获取列名的代码如下:

List<string> columnList = new List<string>();
for (int i = 0; i < idr.FieldCount; i++)
{
    columnList.Add(idr.GetName(i));
}

return columnList;

比使用 GetSchemaTable 的等效版本快得多,我猜是出于同样的原因。

这个问题的精神来自: Ordinal-Based Lookups vs. Name Based Lookups

4

2 回答 2

3

这是使用 ILSpy 提取GetOrdinal的.NET 4.0 的代码。SqlDataReader

public override int GetOrdinal(string name)
{
    SqlStatistics statistics = null;
    int ordinal;
    try
    {
        statistics = SqlStatistics.StartTimer(this.Statistics);
        if (this._fieldNameLookup == null)
        {
            if (this.MetaData == null)
            {
                throw SQL.InvalidRead();
            }
            this._fieldNameLookup = new FieldNameLookup(this, this._defaultLCID);
        }
        ordinal = this._fieldNameLookup.GetOrdinal(name);
    }
    finally
    {
        SqlStatistics.StopTimer(statistics);
    }
    return ordinal;
}

如您所见,没有额外的数据库访问。FieldNameLookup使用 a来存储字段名称,并在第一次调用Hashtable后被缓存。GetOrdinal因此,GetOrdinal调用将为通过 完成的查找增加非常少的开销FieldNameLookup,并且SqlStatistics调用也可能会增加一点开销(尽管可能不会太多)。

一个好的测试是使用 aHashtable来存储索引并在每一行中查找每一列的索引Hashtable。如果性能与对每一行的调用相同GetOrdinal,那么您可以放心地假设开销在FieldNameLookup调用中。

希望有帮助。

于 2013-04-29T19:59:42.780 回答
1

您可以查找 .NET 框架对象的源代码,以了解幕后发生的事情。从这个例子:

override public  Int32 GetOrdinal (string name) { 

            ValidateOpen("GetOrdinal");
            ValidateReader(); 
            DataColumn dc = currentDataTable.Columns[name];

            if (dc != null) {
                return dc.Ordinal;// WebData 113248 
            }
            else{ 
                throw ExceptionBuilder.ColumnNotInTheTable(name, currentDataTable.TableName); 
            }
        } 
于 2013-04-29T19:52:15.170 回答