简体   繁体   中英

SqlDataReader indexer performance

I have some code like this:

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 -...
        }
    }
}

This code takes 40s. After searching a bit, I found out that the rule reader["TrailerId"] takes up 39s in total, the query itself runs very fast!

Removing the "TC." header from "TrailerId" makes it run in 0.6s, the reader["TrailerId"] now only takes 0ms:

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

Is this a bug in the sqldatareader indexer code? I can't make sense of why the second version works so much faster than the first one.

try to get index of "TrailerId" column out of cycle and use it inside; afaik it make this number seek each on record, something like

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 -...
    }
}

Use ordinal index and don't declare the variable each time.
Use a method specific to the data type.
Assuming trailerID is Int32 and position 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 -...
}

With
var trailerId = reader["TrailerId"];
It has to find TrailerId and assign the correct data type to var each loop.

Not sure why the TC made a difference.
Most likely something to do with finding it and then the schema to assign var.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM