.net 基于DataReader名称的查找-What';它实际上是在引擎盖下发生的,这使得它们比循环中基于顺序的查找慢得多?

.net 基于DataReader名称的查找-What';它实际上是在引擎盖下发生的,这使得它们比循环中基于顺序的查找慢得多?,.net,sql,sql-server,sqldatareader,datareader,.net,Sql,Sql Server,Sqldatareader,Datareader,使用多个匹配规则时,基于名称的查找可能比使用整数索引的查找慢一些,这是有道理的。然而,我很难相信,当我们讨论数据集中10-15个[列]条目的平均数量时,这解释了每行3%(或我的项目中的5-7%)的相对成本。值得澄清的是,在前面的声明中,我指的是发生这种“取消引用”的列数,而不是数据集中的记录数。上述成本是在每行查找一次的情况下产生的。所以他们可能会发生很多事情 idr.GetOrdinal(name) // Name based lookup idr[name] // Name-based l

使用多个匹配规则时,基于名称的查找可能比使用整数索引的查找慢一些,这是有道理的。然而,我很难相信,当我们讨论数据集中10-15个[列]条目的平均数量时,这解释了每行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;
List columnList=新列表();
对于(int i=0;i
比使用GetSchemaTable的等效版本快得多,我猜也是出于同样的原因

这一问题的精神来源于: 你可以。从这个例子中:

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); 
            }
        } 

以下是使用ILSpy提取的.NET 4.0中
SqlDataReader
GetOrdinal
代码

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
使用一个
Hashtable
来存储字段名,并在第一次调用
GetOrdinal
时将其加载后缓存。因此,
GetOrdinal
调用将为通过
FieldNameLookup
执行的查找增加非常小的开销,
SqlStatistics
调用也可能会增加一点开销(虽然可能不会太多)

一个好的测试是使用
哈希表
存储索引,并查找该
哈希表
中每一行的每一列的索引。如果性能与为每行调用
GetOrdinal
相同,则可以安全地假设开销在
FieldNameLookup
调用中


希望这能有所帮助。

我想知道一个基于姓名的查找和100个基于姓名的查找之间是否有区别。换句话说,第一次查找是否会将各种模式数据加载到内存中。