<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'Top', 'Query Plans', and 'Parallelism'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=Top,Query+Plans,Parallelism&amp;orTags=0</link><description>Search results matching tags 'Top', 'Query Plans', and 'Parallelism'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Parallel Execution Plans Suck</title><link>http://sqlblog.com/blogs/paul_white/archive/2012/05/02/parallel-row-goals-gone-rogue.aspx</link><pubDate>Wed, 02 May 2012 17:57:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:43147</guid><dc:creator>Paul White</dc:creator><description>&lt;p align="left"&gt;&lt;i&gt;Summary: A deep dive into SQL Server parallelism, and a potential performance problem with parallel plans that use TOP.&lt;/i&gt;&lt;/p&gt;  &lt;p align="left"&gt;There was an interesting &lt;a href="http://dba.stackexchange.com/questions/7233/inaccurate-actual-row-counts-in-parallel-plan" target="_blank"&gt;question&lt;/a&gt; asked by &lt;a href="http://uk.linkedin.com/in/markstoreysmith" target="_blank"&gt;Mark Storey-Smith&lt;/a&gt; on &lt;a href="http://dba.stackexchange.com/"&gt;dba.stackexchange.com&lt;/a&gt; back in October 2011.&amp;#160; He was looking at the execution plan for a query that counts a million rows from a &lt;a href="http://www.sqlmag.com/article/sql-server/virtual-auxiliary-table-of-numbers"&gt;virtual auxiliary table of numbers&lt;/a&gt;.&amp;#160; The query below is a slightly-modified version of the one in the original post:&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:400px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N1 (n) &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#008000;"&gt;-- 10 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    ),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N2 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N1 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;CROSS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N1 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R), &lt;span style="color:#008000;"&gt;-- 100 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N3 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N2 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;CROSS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N2 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R), &lt;span style="color:#008000;"&gt;-- 10,000 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N4 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N3 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;CROSS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N3 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R), &lt;span style="color:#008000;"&gt;-- 100,000,000 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N5 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N4 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;CROSS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N1 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R), &lt;span style="color:#008000;"&gt;-- 1,000,000,000 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N6 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TOP&lt;/span&gt; (1000000) n&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N5&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    )&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    COUNT_BIG(*)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N6&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;OPTION&lt;/span&gt; (RECOMPILE, MAXDOP 1);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;This particular virtual numbers table is capable of producing up to a (&lt;a href="http://en.wikipedia.org/wiki/Billion"&gt;short-scale&lt;/a&gt;) billion rows, via a number of cross joins, but the final common table expression N6 limits it to one million with the TOP clause.&amp;#160; The query plan is just a sequence of cross joins of the ten in-memory rows defined by the first common table expression, N1 (click to enlarge):&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_7B6BCF68.png" target="_blank"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="One million row serial quey plan" border="0" alt="One million row serial quey plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_38AC8430.png" width="660" height="98" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;As usual, the Constant Scan operator is used to generate rows in memory without accessing a physical table, but this one has an interesting property: the ‘virtual table’ contains ten rows, but &lt;b&gt;no columns&lt;/b&gt;.&amp;#160; The query itself only counts rows, it does nothing at all with any column in those rows, and the optimizer contains logic to only project columns that are needed later in the query plan.&amp;#160; If you look at the query plan in SSMS or SQL Sentry Plan Explorer, you will see that the Constant Scans have a blank output columns list; they project no columns at all.&lt;/p&gt;

&lt;h3 align="left"&gt;Execution Plans Suck&lt;/h3&gt;

&lt;p align="left"&gt;The plan above does illustrate an important concept in plan-reading: &lt;b&gt;execution plans start executing at the left-most node&lt;/b&gt;.&amp;#160; People are often told to read execution plans from the top-right, and that is fine if you just want to follow the flow of data – so long as you bear in mind that the flow of program control starts at the root (far left).&lt;/p&gt;

&lt;p align="left"&gt;Rob Farley (&lt;a href="http://sqlblog.com/blogs/rob_farley"&gt;blog&lt;/a&gt; | &lt;a href="https://twitter.com/#!/rob_farley"&gt;twitter&lt;/a&gt;) sums this up by saying “execution plans suck”; a reference to the fact that rows are pulled up the tree by parent operators requesting rows, &lt;b&gt;one at a time&lt;/b&gt;, from the its child operator(s).&amp;#160; Query execution follows a &lt;b&gt;demand-based pipeline model&lt;/b&gt; (except in batch mode in parallel 2012 column-store plans, but that is a tangent we will not be pursuing today).&amp;#160; I’m not going to labour the point, but if you are interested to understand this better, take a look at my &lt;a href="http://sqlblog.com/blogs/paul_white/archive/2010/08/05/iterators-query-plans-and-why-they-run-backwards.aspx"&gt;previous post&lt;/a&gt; on the topic, or Brad Schulz’s &lt;a href="http://bradsruminations.blogspot.co.nz/2010/11/second-in-life-of-query-operator.html"&gt;entertaining overview&lt;/a&gt;.&lt;/p&gt;

&lt;p align="left"&gt;Let’s look at the execution plan (with runtime statistics) changing the TOP specification from one million to one hundred to make it easier to see what’s going on:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_4461CB62.png" target="_blank"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="TOP 100 Plan" border="0" alt="TOP 100 Plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_6187736C.png" width="640" height="146" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;I’m just showing part of the plan for clarity.&amp;#160; There are another four Constant Scans off to the right that all produce one row.&amp;#160; If query plans really did start executing at the top right, we would expect one row from the right-most Constant Scan, ten rows from its parent, and one hundred at the next operator up the tree (working right to left).&amp;#160; As it is, the expected pattern (one, then ten, then one hundred) appears closest to the Top operator.&amp;#160; This only makes sense if a row at a time is sucked up the plan from the root.&amp;#160; The pipelined (row-by-row) model also explains why execution stops after 100 rows; the Top operator in the plan simply stops requesting a new row from its immediate child at that point.&lt;/p&gt;

&lt;h3 align="left"&gt;The Question&lt;/h3&gt;

&lt;p align="left"&gt;Back to the main thrust of today’s post.&amp;#160; The question arose when Mark ran his query with parallelism enabled:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:400px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N1 (n) &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#008000;"&gt;-- 10 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    ),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N2 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N1 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;CROSS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N1 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R), &lt;span style="color:#008000;"&gt;-- 100 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N3 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N2 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;CROSS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N2 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R), &lt;span style="color:#008000;"&gt;-- 10,000 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N4 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N3 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;CROSS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N3 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R), &lt;span style="color:#008000;"&gt;-- 100,000,000 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N5 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N4 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;CROSS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N1 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R), &lt;span style="color:#008000;"&gt;-- 1,000,000,000 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N6 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TOP&lt;/span&gt; (1000000) n&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N5&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    )&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    COUNT_BIG(*)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N6&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;OPTION&lt;/span&gt; (RECOMPILE, MAXDOP 2);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;That produces an actual execution plan like this (click to enlarge):&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_49A08C46.png" target="_blank"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Parallel Top One Million" border="0" alt="Parallel Top One Million" src="http://sqlblog.com/blogs/paul_white/image_thumb_624FB389.png" width="644" height="66" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;The question relates to the actual number of rows shown entering and leaving the Gather Streams exchange operator:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_388C3896.png" target="_blank"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Gather Streams Exchange" border="0" alt="Gather Streams Exchange" src="http://sqlblog.com/blogs/paul_white/image_thumb_360306D8.png" width="367" height="88" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;As expected, one million rows leave the exchange operator, but the plan shows &lt;b&gt;1,004,588&lt;/b&gt; rows entering it.&amp;#160; So the question is, are the row counts wrong, or if not, where did the rows go?&lt;/p&gt;

&lt;h3 align="left"&gt;The Answer&lt;/h3&gt;

&lt;p align="left"&gt;As you may know, the answer lies in the fact that exchanges &lt;a href="http://www.simple-talk.com/sql/learn-sql-server/understanding-and-using-parallelism-in-sql-server/"&gt;contain buffers&lt;/a&gt;.&amp;#160; For efficiency reasons, rows are not passed across threads one by one as in the normal model discussed above.&amp;#160; Instead, producer threads (on the right side of the exchange operator) pack rows one at a time into packets, and push completed packets across the &lt;a href="http://blogs.msdn.com/b/craigfr/archive/2006/10/25/the-parallelism-operator-aka-exchange.aspx"&gt;exchange&lt;/a&gt;.&amp;#160; Consumer thread(s) on the left side of the exchange retrieve rows one at a time from the current packet on demand, re-establishing the demand-based pipeline model.&amp;#160; The internal class name for the packets, by the way, is Class eXchange PACKET – which gives us the familiar CXPACKET moniker.&lt;/p&gt;

&lt;p align="left"&gt;Exploring the detail at little more, we can see from the execution plan that the two independent producer threads to the right of the exchange pack a total of 499,225 + 505,363 = &lt;b&gt;1,004,588&lt;/b&gt; rows into packets, and the single consumer thread (thread zero) retrieves just the one million rows needed by the Top operator:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_30A54DC8.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Per Thread Row Counts" border="0" alt="Per Thread Row Counts" src="http://sqlblog.com/blogs/paul_white/image_thumb_4064E2CC.png" width="457" height="116" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;So, the actual row counts shown on the execution plan are correct, and the ‘missing rows’ are accounted for by rows that were added to packets but not ultimately needed by the consumer.&amp;#160; After the one millionth row is passed by the Top to the Stream Aggregate (and remember all these things happen one row at a time), the next time the Top gets control, it starts the process of shutting down the pipeline below it, rather than asking the Gather Streams exchange for another row.&amp;#160; Glossing over the finer details a little, instead of the Top calling a &lt;strong&gt;GetRow&lt;/strong&gt;() method on the &lt;i&gt;Gather Streams&lt;/i&gt; iterator, it calls a &lt;strong&gt;Close&lt;/strong&gt;() method instead.&lt;/p&gt;

&lt;h3 align="left"&gt;SQL Server 2008+&lt;/h3&gt;

&lt;p align="left"&gt;On SQL Server 2005 that is the end of the story.&amp;#160; On SQL Server 2008 and later (including 2012), there is more.&amp;#160; Let’s run the query one more time, but this time with a degree of parallelism of three, rather than two.&amp;#160; Sometimes, we will get a plan that contains this sort of row count arrangement at the Gather Streams:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_6BC903C6.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="DOP 3 Gather Streams" border="0" alt="DOP 3 Gather Streams" src="http://sqlblog.com/blogs/paul_white/image_thumb_693FD208.png" width="354" height="95" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;Much the same as before, a few thousand extra rows are processed by the producer threads than are ultimately needed by the consumer.&amp;#160; That’s fine, of course, the threads in a parallel plan execute independently, so there are bound to be small timing differences that lead to this sort of effect.&amp;#160; Every so often, however, executing this query on SQL Server 2008 or above will produce a result like this:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_51C51DD7.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Monster Row Count" border="0" alt="Monster Row Count" src="http://sqlblog.com/blogs/paul_white/image_thumb_4F3BEC19.png" width="363" height="92" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;Whoa.&amp;#160; Nearly &lt;b&gt;335 million rows&lt;/b&gt; entering the exchange – and the query now runs for &lt;b&gt;50 seconds&lt;/b&gt; or so, having run consistently for around &lt;b&gt;200ms&lt;/b&gt; previously.&amp;#160; Looking at the per-thread actual row counts is revealing:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_4CB2BA5B.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Monster Per Thread" border="0" alt="Monster Per Thread" src="http://sqlblog.com/blogs/paul_white/image_thumb_7163D1D2.png" width="546" height="140" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;If everything were perfectly balanced, we might expect each of the three producer threads to process around 333,000 rows.&amp;#160; Indeed, thread 1 and thread 2 are in this ballpark area, but thread 3 ground through &lt;b&gt;334 million rows&lt;/b&gt; on its own!&amp;#160; I should mention that there is nothing special about thread 3 (you are as likely to find the huge row count on thread 1 or thread 2, the labels are arbitrary).&amp;#160; Indeed, the problem can occur on any or all threads, as a second example run at DOP 3 shows below:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_68279691.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="DOP 3 Second Example" border="0" alt="DOP 3 Second Example" src="http://sqlblog.com/blogs/paul_white/image_thumb_21CA307C.png" width="368" height="95" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_1F40FEBE.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="DOP 3 Per Thread Row Counts 2" border="0" alt="DOP 3 Per Thread Row Counts 2" src="http://sqlblog.com/blogs/paul_white/image_thumb_5CEDE67A.png" width="565" height="140" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;This time two threads went rogue, resulting in over &lt;b&gt;667 million rows&lt;/b&gt; being processed in a total execution time of &lt;b&gt;67 seconds&lt;/b&gt;.&lt;/p&gt;

&lt;h3 align="left"&gt;Parallelism Problems?&lt;/h3&gt;

&lt;p align="left"&gt;There are other parallelism (exchange) operators in the plan, though we have concentrated only on the final Gather Streams operator so far.&amp;#160; By the way, Gather Streams is also known as a &lt;b&gt;Start Parallelism&lt;/b&gt; operator – a name that might surprise you since it seems to mark the &lt;b&gt;end&lt;/b&gt; of parallelism in the plan, rather than the start.&amp;#160; Remember that execution plans suck.&amp;#160; The ‘final’ Gather Streams is in fact the first operator to start executing, and it is responsible for &lt;b&gt;starting the parallel workers&lt;/b&gt; and attaching them to the threads that were reserved for this plan at the very start of execution.&amp;#160; Anyway, I digress.&amp;#160; Let’s look at the next exchange in the plan – reading left to right of course.&amp;#160; This is a &lt;i&gt;Repartition Streams&lt;/i&gt; exchange operating in &lt;i&gt;Round Robin&lt;/i&gt; distribution mode:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_5A64B4BC.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Repartition Streams" border="0" alt="Repartition Streams" src="http://sqlblog.com/blogs/paul_white/image_thumb_30A139C9.png" width="570" height="262" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;This shows that 1,000 rows arriving on the producer side of the exchange, and a total of 668 on the consumer side.&amp;#160; Not shown in the diagram above, the producer side has 340 rows on thread 1, and 330 rows on each of thread 2 and thread 3.&amp;#160; Note that these are &lt;b&gt;not the same threads&lt;/b&gt; as the ones we saw numbered the same way before.&amp;#160; The numbering scheme is restarted for each independent parallel zone in the plan (and zones are bounded by a parallelism operator of one sort or another).&amp;#160; Anyway, the point is that the rows are pretty evenly distributed on the producer side of the exchange.&lt;/p&gt;

&lt;p align="left"&gt;On the consumer side (row counts illustrated above), things are rather different.&amp;#160; Thread 1 (in this zone) processes 334 rows, thread 2 gets 333, and thread 3 gets only one.&amp;#160; Now these &lt;b&gt;are&lt;/b&gt; the same threads as shown in the 667 million row diagram.&amp;#160; I mentioned that &lt;b&gt;parallel zones&lt;/b&gt; are bordered by parallelism operators; the current zone is bordered by the Repartition Streams on its right side, and by the Gather Streams on its left.&amp;#160; The same three threads are &lt;b&gt;consumers&lt;/b&gt; at the &lt;i&gt;Repartition Streams&lt;/i&gt;, and &lt;b&gt;producers&lt;/b&gt; at the &lt;i&gt;Gather Streams&lt;/i&gt; operator:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_2E1E64BA.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Consumer Producer Branch" border="0" alt="Consumer Producer Branch" src="http://sqlblog.com/blogs/paul_white/image_thumb_1E2F1FF6.png" width="660" height="205" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;There is a clear relationship between the thread row counts at the consumer side of the Repartition Streams (334, 333, and 1 row) and the row counts at the producer side of the Gather Streams (334 million, 333 million, 338,614 rows).&amp;#160; The two problematic threads have multiplied their row counts by a factor of one million – precisely the effect of the &lt;b&gt;six cross joins&lt;/b&gt; in this parallelism zone.&amp;#160; The Constant Scan virtual tables contain ten rows each, and multiplying by ten, six times over, gives a factor of one million.&lt;/p&gt;

&lt;h3 align="left"&gt;Rogue Row Goals&lt;/h3&gt;

&lt;p align="left"&gt;Thread 3 in the example above ends up processing 338,614 rows.&amp;#160; This number has no special significance, except it shows that this thread did not run this portion of the plan to completion.&amp;#160; If it had, the single row it started with would have ended up as one million rows by the time it had been cross-joined six times with the ten-row Constant Scan table.&lt;/p&gt;

&lt;p align="left"&gt;This is the &lt;b&gt;row goal&lt;/b&gt; in action (if you need a details on exactly what a row goal is, please see &lt;a href="http://sqlblog.com/blogs/paul_white/archive/2010/08/18/inside-the-optimiser-row-goals-in-depth.aspx"&gt;my previous post&lt;/a&gt;).&amp;#160; Essentially, though, things like a TOP operator or a FAST n hint set a row goal.&amp;#160; Plans normally run to completion, but row goals modify this, producing a plan that tries to optimize for a &lt;b&gt;certain number of rows&lt;/b&gt; rather than the full potential set.&amp;#160; The TOP operator is even more special.&amp;#160; As discussed briefly before, TOP can bring execution to an early end – instead of continuing to ask for rows from its child iterator, it calls the &lt;b&gt;Close()&lt;/b&gt; method instead.&amp;#160; This call filters down the tree, and execution comes to an early end.&amp;#160; (Strictly, row goals affect optimizer choices and plan costing rather than being associated with the early end of execution, but I like the phrase ‘rogue row goal’).&lt;/p&gt;

&lt;p align="left"&gt;So, thread 3 did not run to completion – it responded to the early Close() call and only processed 338 thousand of the one million rows it could have produced if left alone.&amp;#160; Threads 1 and 2 never received the Close() call, or chose to ignore it.&amp;#160; These two rogues went on to process their full potential row set – 667 million rows – despite the fact that the TOP had seen the million rows it needed and was waiting for operations elsewhere in the parallel plan to stop.&amp;#160; We can see this by looking at the &lt;a href="http://msdn.microsoft.com/en-us/library/ms188743.aspx"&gt;sys.dm_os_waiting_tasks&lt;/a&gt; DMV while the long-running query is executing:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_06DDBED6.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="e_waitPortClose" border="0" alt="e_waitPortClose" src="http://sqlblog.com/blogs/paul_white/image_thumb_1D505D5D.png" width="662" height="173" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;The output is split across two lines for readability, and shows &lt;b&gt;execution context zero&lt;/b&gt; blocked on a &lt;b&gt;CXPACKET&lt;/b&gt; wait by both execution context 1 and execution context 3.&amp;#160; Execution context zero is always thread zero – the so-called coordinator thread that runs the serial part of the execution plan to the left of the left-most &lt;i&gt;Gather Streams&lt;/i&gt; operator.&amp;#160; Put another way, context zero always runs the part of the plan &lt;i&gt;before&lt;/i&gt; (reading left to right) the &lt;em&gt;Start Parallelism&lt;/em&gt; operator (and therefore always runs a serial plan).&lt;/p&gt;

&lt;p align="left"&gt;OK, so CXPACKET means the thread is involved in a parallelism-related wait.&amp;#160; The extra detail in the &lt;i&gt;resource_description&lt;/i&gt; column tells us that the wait is occurring at the node id 2.&amp;#160; Checking the execution plan, we see that node 2 is indeed the Gather Streams exchange:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_2905A48F.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Node 2" border="0" alt="Node 2" src="http://sqlblog.com/blogs/paul_white/image_thumb_2E741533.png" width="365" height="102" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;The wait type of &lt;i&gt;e_waitPortClose&lt;/i&gt; means the consumer is waiting for the port to close.&amp;#160; If you are wondering what a &lt;b&gt;port&lt;/b&gt; is in this context, I will just say the parallelism architecture is more complex than just &lt;b&gt;CXPACKET&lt;/b&gt; – the wiring includes a &lt;b&gt;CXPort&lt;/b&gt; class, a &lt;b&gt;CXPipe&lt;/b&gt; class, a &lt;b&gt;CXTransLocal&lt;/b&gt; (local transport) class and a &lt;b&gt;CXTransRemote&lt;/b&gt; class (for the Parallel Data Warehouse edition).&amp;#160; There is also a linked map structure that shows how the various pipes, ports, and transports connect together.&amp;#160; Closing the port is one step in shutting down part of a parallel plan which is running on the other side of an exchange (via a transport, pipe, and port).&amp;#160; The stack trace below shows thread zero waiting for the port to close:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_69057809.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Stack Trace" border="0" alt="Stack Trace" src="http://sqlblog.com/blogs/paul_white/image_thumb_7FE44985.png" width="536" height="217" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;The important things are that (a) this problem &lt;b&gt;does not occur&lt;/b&gt; in SQL Server 2005; and (b) a number of changes were made to the internal parallelism implementation in SQL Server 2008.&amp;#160; These changes seem to have introduced a bug, where the consumer can wait for the port to close, but one or more producers either ignore the request, or fail to check for it, and go on to process the whole potential result set instead of stopping early.&lt;/p&gt;

&lt;h3 align="left"&gt;Not Just Nested Loops&lt;/h3&gt;

&lt;p align="left"&gt;Fellow SQLblogger Joe Chang (&lt;a href="http://sqlblog.com/blogs/joe_chang/"&gt;blog&lt;/a&gt;) suggested in the comments that this problem may only occur with parallel nested loops joins.&amp;#160; The script below reproduces the problem with parallel hash joins:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:800px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N1 (n) &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#008000;"&gt;-- 10 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1 &lt;span style="color:#0000ff;"&gt;UNION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ALL&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; 1&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    ),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N2 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N1 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N1 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; L.n % 1 = R.n % 1), &lt;span style="color:#008000;"&gt;-- 100 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N3 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N2 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N2 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; L.n % 1 = R.n % 1), &lt;span style="color:#008000;"&gt;-- 10,000 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N4 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N3 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N3 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; L.n % 1 = R.n % 1), &lt;span style="color:#008000;"&gt;-- 100,000,000 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N5 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; L.n &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N4 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; L &lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; N1 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; R &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; L.n % 1 = R.n % 1), &lt;span style="color:#008000;"&gt;-- 1,000,000,000 rows&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    N6 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TOP&lt;/span&gt; (1000000) n&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N5&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    )&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    COUNT_BIG(*)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; N6&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;OPTION&lt;/span&gt; (RECOMPILE, MAXDOP 4, QUERYTRACEON 8649);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;The full execution plan is rather large, but the key part is shown below (click to enlarge):&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_34C9C4C4.png" target="_blank"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="parallel hash join plan" border="0" alt="parallel hash join plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_3FA6A60C.png" width="660" height="274" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;Yes, that is &lt;strong&gt;700 million rows&lt;/strong&gt; entering the Gather Streams exchange (click to enlarge):&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_1576F824.png" target="_blank"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="parallel hash row counts" border="0" alt="parallel hash row counts" src="http://sqlblog.com/blogs/paul_white/image_thumb_52B7ACEB.png" width="644" height="229" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;The bug does not occur in every query plan with Top and parallelism, but the choice of nested loops join is not the cause.&lt;/p&gt;

&lt;h3 align="left"&gt;Final Thoughts&lt;/h3&gt;

&lt;p align="left"&gt;The potential for poor performance and excessive processor usage here is obvious; and the chance of hitting the race condition gets &lt;b&gt;worse&lt;/b&gt; at higher DOP.&amp;#160; With eight threads per parallel zone (DOP 8), I hit this issue almost every time on SQL Server 2008, 2008 R2, and 2012.&amp;#160; Because this behaviour does not occur on SQL Server 2005, but does on 2008 and later, I have filed this as a bug on Connect:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="https://connect.microsoft.com/SQLServer/feedback/details/740234/poor-performance-with-parallelism-and-top"&gt;https://connect.microsoft.com/SQLServer/feedback/details/740234/poor-performance-with-parallelism-and-top&lt;/a&gt;&lt;/p&gt;

&lt;h4 align="left"&gt;Further Reading:&lt;/h4&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/archive/2010/08/05/iterators-query-plans-and-why-they-run-backwards.aspx"&gt;http://sqlblog.com/blogs/paul_white/archive/2010/08/05/iterators-query-plans-and-why-they-run-backwards.aspx&lt;/a&gt; 

  &lt;br /&gt;&lt;a title="http://bradsruminations.blogspot.co.nz/2010/11/second-in-life-of-query-operator.html" href="http://bradsruminations.blogspot.co.nz/2010/11/second-in-life-of-query-operator.html"&gt;http://bradsruminations.blogspot.co.nz/2010/11/second-in-life-of-query-operator.html&lt;/a&gt; 

  &lt;br /&gt;&lt;a title="http://www.simple-talk.com/sql/learn-sql-server/understanding-and-using-parallelism-in-sql-server/" href="http://www.simple-talk.com/sql/learn-sql-server/understanding-and-using-parallelism-in-sql-server"&gt;http://www.simple-talk.com/sql/learn-sql-server/understanding-and-using-parallelism-in-sql-server&lt;/a&gt; 

  &lt;br /&gt;&lt;a title="http://blogs.msdn.com/b/craigfr/archive/2006/10/25/the-parallelism-operator-aka-exchange.aspx" href="http://blogs.msdn.com/b/craigfr/archive/2006/10/25/the-parallelism-operator-aka-exchange.aspx"&gt;http://blogs.msdn.com/b/craigfr/archive/2006/10/25/the-parallelism-operator-aka-exchange.aspx&lt;/a&gt; 

  &lt;br /&gt;&lt;a title="http://sqlblog.com/blogs/paul_white/archive/2010/08/18/inside-the-optimiser-row-goals-in-depth.aspx" href="http://sqlblog.com/blogs/paul_white/archive/2010/08/18/inside-the-optimiser-row-goals-in-depth.aspx"&gt;http://sqlblog.com/blogs/paul_white/archive/2010/08/18/inside-the-optimiser-row-goals-in-depth.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;© 2012 Paul White 
  &lt;br /&gt;Twitter: &lt;a href="http://twitter.com/SQL_Kiwi"&gt;@SQL_Kiwi&lt;/a&gt; (with an underscore) 

  &lt;br /&gt;Email: &lt;a href="mailto:SQLkiwi@gmal.com"&gt;SQLkiwi@gmal.com&lt;/a&gt; (no underscore)&lt;/p&gt;</description></item></channel></rss>