4

我有一些这样的代码:

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 秒。查了一下,发现rule reader["TrailerId"]一共占用了39s,查询本身跑的很快!

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

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

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

4

2 回答 2

0

使用序数索引,不要每次都声明变量。
使用特定于数据类型的方法。
假设 trailID 是 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 的模式有关。

于 2013-07-23T13:22:26.933 回答
0

尝试使“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 -...
    }
}
于 2013-07-23T13:00:57.417 回答