【问题标题】:SqlDataReader indexer performanceSqlDataReader 索引器性能
【发布时间】:2013-07-22 13:12:54
【问题描述】:

我有一些这样的代码:

using (var cmd = TransicsCommand.GetFleetCommand())
{
    cmd.CommandText = @"
                        SELECT dr.DeviceId, dr.DeviceTruckRelationId, dr.TruckId, dr.RelationCreatedOn,
                        dl.DriverLoginId, dl.DriverId, dl.UserType, dl.LoginType, dl.SecondsSince DriverLoginCreated,
                        Action.ActionId, Action.ActionTimestamp, Action.UserType actionusertype, Action.TripreportId,
                        DeviceHeaderData.DeviceHeaderid, DeviceHeaderData.Odo, DeviceHeaderData.X, DeviceHeaderData.Y,
                        DeviceHeaderData.ValidPosition, DeviceHeaderData.Tfu,
                        DeviceHeaderData.FuelPercentage, DeviceHeaderData.Speed, 
                        InstructionsetAction.VersionId,
                        tc.CouplingId, tc.TrailerId, tc.CouplingEvent, tc.TrailerEntry, tc.SecondsSince
                        FROM TripReport.Action Action
                        INNER JOIN DeviceHeader.Data DeviceHeaderData ON Action.DeviceHeaderId = DeviceHeaderData.DeviceHeaderId
                        INNER JOIN Instructionset.Action InstructionsetAction  ON InstructionsetAction.ActionId = Action.ActionId
                        INNER JOIN DeviceHeader.Truck dht ON Action.DeviceHeaderId = dht.DeviceHeaderId
                        INNER JOIN Device.TruckRelation dr ON dht.DeviceRelationId = dr.DeviceTruckRelationId 
                        LEFT OUTER JOIN [DeviceHeader].[LoginSession] dhls ON dhls.DeviceHeaderId = dht.DeviceHeaderId
                        LEFT OUTER JOIN [LogIn].DriverLogin as dl ON dhls.DriverLoginId = dl.DriverLoginId
                        LEFT OUTER JOIN [DeviceHeader].[TrailerCoupling] dhtc ON dhtc.DeviceHeaderId = dht.DeviceHeaderId
                        LEFT OUTER JOIN [Trailer].[Coupling] as tc ON dhtc.CouplingId = tc.CouplingId ";

    using (var reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {   
            Stopwatch sw = new Stopwatch();
            sw.Start();
            var trailerId = reader["TrailerId"];
            sw.Stop();
            Debug.WriteLine(trailerId + "-" + sw.ElapsedMilliseconds);//10s - 8s -...
        }
    }
}

此代码需要 40 秒。搜索了一下,发现规则reader["TrailerId"]一共占用了39s,查询本身跑的很快!

删除“TC”。 "TrailerId" 的标头使其在 0.6 秒内运行,阅读器 ["TrailerId"] 现在只需要 0 毫秒:

SELECT ..., tc.CouplingId, TrailerId,...

这是 sqldatareader 索引器代码中的错误吗?我不明白为什么第二个版本比第一个版本运行得这么快。

【问题讨论】:

  • 存储过程怎么样

标签: c# .net performance sqldatareader


【解决方案1】:

使用序数索引,不要每次都声明变量。
使用特定于数据类型的方法。
假设 TrailerID 为 Int32,位置为 22。

Stopwatch sw = new Stopwatch();
Int32 trailerID;
while (reader.Read())
{   
    sw.Start();
    trailerId = reader.GetInt(22);
    sw.Stop();
    Debug.WriteLine(trailerId + "-" + sw.ElapsedMilliseconds);//10s - 8s -...
}

与
var trailId = reader["TrailerId"];
它必须找到 TrailerId 并为每个循环分配正确的数据类型。

不确定 TC 为何有所作为。
很可能与找到它以及分配 var 的架构有关。

【讨论】:

    【解决方案2】:

    尝试在循环中获取“TrailerId”列的索引并在内部使用它; afaik 它使这个数字在记录中寻找每个,就像

    using (var reader = cmd.ExecuteReader())
    {
        int idx = -1;
        while (reader.Read())
        {   
            if (idx==-1) idx = reader.GetOrdinal("TrailerId");
            Stopwatch sw = new Stopwatch();
            sw.Start();
            var trailerId = reader[idx];
            sw.Stop();
            Debug.WriteLine(trailerId + "-" + sw.ElapsedMilliseconds);//10s - 8s -...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      • 2020-03-16
      • 2016-05-01
      • 2017-08-29
      • 2010-10-29
      • 1970-01-01
      相关资源
      最近更新 更多