Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Query performance depends on a lot of things, like the indexes that are present, the actual data, how stale the statistics about the data present are etc. SQL query plan optimizer looks at these different metrics to come up with an efficient query plan. So, any straightforward answer that says query 1 is always better than query 2 or the opposite would be incorrect.</p> <p>That said, my answer below tries to explain the articles stance and how <code>Skip(1).Any()</code> could be better(marginally) than doing a <code>Count() &gt; 1</code>. The second query though being bigger in size and mostly unreadable looks like it could be interpreted in an efficient fashion. Again, this depends on things aforementioned. The idea is that the number of rows that the database has to look into to figure out the result is more in case of <code>Count()</code>. In the count case, assuming that the required indexes are there (a clustered index on Id to make the OrderBy in second case efficient), the db has to go through count number of rows. In the second case, it has to go through a maximum of two rows to arrive at the answer.</p> <p>Lets get more scientific in our analysis and see if my above theory holds any ground. For this, I am creating a dummy database of customers. The Customer type looks like this,</p> <pre><code>public class Customer { public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } } </code></pre> <p>I am seeding the database with some 100K random rows(I really have to prove this) using this code,</p> <pre><code> for (int j = 0; j &lt; 100; j++) { using (CustomersContext db = new CustomersContext()) { Random r = new Random(); for (int i = 0; i &lt; 1000; i++) { Customer c = new Customer { Name = Guid.NewGuid().ToString(), Age = r.Next(0, 100) }; db.Customers.Add(c); } db.SaveChanges(); } } </code></pre> <p>Sample code <a href="https://gist.github.com/raghuramn/5454730" rel="nofollow noreferrer">here</a>.</p> <p>Now, the queries that I am going to use are as follows,</p> <pre><code>db.Customers.Where(c =&gt; c.Age == 26).Count() &gt; 1; // scenario 1 db.Customers.Where(c =&gt; c.Age == 26).OrderBy(c =&gt; c.ID).Skip(1).Any() // scenario 2 </code></pre> <p>I have started SQL profiler to catch the query plans. The captured plans look as follows,</p> <h2>Scenario 1:</h2> <p>Check out the estimated cost and actual row count for scenario 1 in the above images. <img src="https://i.stack.imgur.com/GkJEa.png" alt="Scenario 1 - Estimated Cost"> <img src="https://i.stack.imgur.com/04iJv.png" alt="Scenario 1 - Actual row count"></p> <h2>Scenario 2:</h2> <p>Check out the estimated cost and actual row count for scenario 2 in the below images. <img src="https://i.stack.imgur.com/Xd7yE.png" alt="Scenario 2 - Estimated Cost"> <img src="https://i.stack.imgur.com/U4Mw2.png" alt="Scenario 2 - Actual row count"></p> <p>As per the initial guess, the estimated cost and the number of rows is lesser in the Skip and any case as compared to Count case.</p> <h2>Conclusion:</h2> <p>All this analysis aside, as many others have commented earlier, these are not the kind of performance optimizations you should try to do in your code. Things like these hurt readability with very minimal(I would say non-existent) perf benefit. I just did this analysis for fun and would never use this as a basis for choosing scenario 2. I would measure and see if doing a <code>Count()</code> is actually hurting to change the code to use <code>Skip().Any()</code>.</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.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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