Note that there are some explanatory texts on larger screens.

plurals
  1. POLinq To Sql surprisingly fast retreving data. Is it normal that it is 10x faster than ADO?
    primarykey
    data
    text
    <p>I'm currently learning Linq to Sql and Im very surprised by the performance of selecting data. I'm retreving joined data from few tables. I select about 40k of rows. Mapping this data to objects using ADO times about 35s, using NHbiernate times about 130s and what is suspicious using Linq To Sql only 3,5s. Additionally I would like to write that I'm using immediately loading which looks like: </p> <pre><code>THESIS th = new THESIS(connectionString); DataLoadOptions dlo = new DataLoadOptions(); dlo.LoadWith&lt;NumericFormula&gt;(x =&gt; x.RPN); dlo.LoadWith&lt;RPN&gt;(x =&gt; x.RPNDetails); dlo.LoadWith&lt;RPNDetail&gt;(x =&gt; x.Parameter); th.LoadOptions = dlo; th.Log = Console.Out; </code></pre> <p>Looking to the logs when I'm iterating I can't see that Linq To Sql generate some additional queries to database.</p> <p>I'm very surprised by huge differences in performance and I wonder that maybe I don't understand something. </p> <p>Could someone explain me why it works so fast? To measure time I'm using Stopwatch class.</p> <p>ADO.NET Code:</p> <pre><code>public static List&lt;NumericFormulaDO&gt; SelectAllNumericFormulas() { var nFormulas = new List&lt;NumericFormulaDO&gt;(); string queryString = @" SELECT * FROM NumericFormula nf Left Join Unit u on u.Unit_Id = nf.Unit_Id Left Join UnitType ut on ut.UnitType_Id = u.UnitType_Id Join RPN r on r.RPN_Id = nf.RPN_Id Join RPNDetails rd on rd.RPN_Id = r.RPN_Id Join Parameter par on par.Parameter_Id = rd.Parameter_Id where nf.NumericFormula_Id&lt;=10000"; using (var connection = new SqlConnection(connectionString)) { var command = new SqlCommand(queryString, connection); connection.Open(); using (var reader = command.ExecuteReader()) { while (reader.Read()) { var det = new RPNDetailsDO(); det.RPNDetails_Id = Int32.Parse(reader["RPNDetails_Id"].ToString()); det.RPN_Id = Int32.Parse(reader["RPN_Id"].ToString()); det.Identifier = reader["Identifier"].ToString(); det.Parameter.Architecture = reader["Architecture"].ToString(); det.Parameter.Code = reader["Code"].ToString(); det.Parameter.Description = reader["Description"].ToString(); det.Parameter.Parameter_Id = Int32.Parse(reader["Parameter_Id"].ToString()); det.Parameter.ParameterType = reader["ParameterType"].ToString(); det.Parameter.QualityDeviationLevel = reader["QualityDeviationLevel"].ToString(); if (nFormulas.Count &gt; 0) { if (nFormulas.Any(x =&gt; x.RPN.RPN_Id == Int32.Parse(reader["RPN_Id"].ToString()))) { nFormulas.First(x=&gt;x.RPN.RPN_Id == Int32.Parse(reader["RPN_Id"].ToString())).RPN.RPNDetails.Add(det); } else { NumericFormulaDO nFormula = CreatingNumericFormulaDO(reader, det); nFormulas.Add(nFormula); //System.Diagnostics.Trace.WriteLine(nFormulas.Count.ToString()); } } else { NumericFormulaDO nFormula = CreatingNumericFormulaDO(reader, det); nFormulas.Add(nFormula); //System.Diagnostics.Trace.WriteLine(nFormulas.Count.ToString()); } } } } return nFormulas; } private static NumericFormulaDO CreatingNumericFormulaDO(SqlDataReader reader, RPNDetailsDO det) { var nFormula = new NumericFormulaDO(); nFormula.CalculateDuringLoad = Boolean.Parse(reader["CalculateDuringLoad"].ToString()); nFormula.NumericFormula_Id = Int32.Parse(reader["NumericFormula_Id"].ToString()); nFormula.RPN.RPN_Id = Int32.Parse(reader["RPN_Id"].ToString()); nFormula.RPN.Formula = reader["Formula"].ToString(); nFormula.Unit.Name = reader["Name"].ToString(); if (reader["Unit_Id"] != DBNull.Value) { nFormula.Unit.Unit_Id = Int32.Parse(reader["Unit_Id"].ToString()); nFormula.Unit.UnitType.Type = reader["Type"].ToString(); nFormula.Unit.UnitType.UnitType_Id = Int32.Parse(reader["UnitType_Id"].ToString()); } nFormula.RPN.RPNDetails.Add(det); return nFormula; } </code></pre> <hr> <p>LINQ to SQL Code:</p> <pre><code>THESIS th = new THESIS(connectionString); DataLoadOptions dlo = new DataLoadOptions(); dlo.LoadWith&lt;NumericFormula&gt;(x =&gt; x.RPN); dlo.LoadWith&lt;RPN&gt;(x =&gt; x.RPNDetails); dlo.LoadWith&lt;RPNDetail&gt;(x =&gt; x.Parameter); th.LoadOptions = dlo; th.Log = Console.Out; var nFormulas = th.NumericFormulas.ToList&lt;NumericFormula&gt;(); </code></pre> <hr> <p>NHibernate Code:</p> <pre><code>IQueryable&lt;NumericFormulaDO&gt; nFormulas = session.Query&lt;NumericFormulaDO&gt;() .Where(x=&gt;x.NumericFormula_Id &lt;=10000); List&lt;NumericFormulaDO&gt; nForList = new List&lt;NumericFormulaDO&gt;(); nForList = nFormulas.ToList&lt;NumericFormulaDO&gt;(); </code></pre> <p>Related to your comments you can see that in ADO I'm using <code>SqlReader</code> and in LINQ I try to use immediate execution. </p> <p>Of course it is possible that my mapping "algorithm" in ADO part it's not very good but NHibernate is much more slow than ADO (4x slower) so I wonder if for sure is everything alright in LINQ to SQL part because I think in NHibernate is everything good and after all is much more slow than little confusing ADO part.</p> <p>Thank you guys for responses. </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload