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 秒かかります。少し調べてみたところ、reader["TrailerId"]ルールが合計で 39 秒かかり、クエリ自体が非常に高速に実行されることがわかりました。

「TC」を削除します。"TrailerId" のヘッダーは 0.6 秒で実行され、リーダー ["TrailerId"] は 0 ミリ秒しかかかりません:

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

これは sqldatareader インデクサー コードのバグですか? 2 番目のバージョンが最初のバージョンよりもはるかに高速に動作する理由がわかりません。

4

2 に答える 2

0

「TrailerId」列のインデックスをサイクルから取得して、内部で使用してみてください。私の知る限り、この番号はレコードごとにシークします。

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 に答える
0

序数インデックスを使用し、毎回変数を宣言しないでください。
データ型に固有のメソッドを使用してください。
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 TrailerId
= reader["TrailerId"]; を使用
TrailerId を見つけて、ループごとに正しいデータ型を var に割り当てる必要があります。

TC が違いを生んだ理由がわかりません。
ほとんどの場合、それを見つけて、var を割り当てるスキーマに関係があります。

于 2013-07-23T13:22:26.933 に答える