Search results matching tag 'Performance'http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&tag=Performance&orTags=0Search results matching tag 'Performance'en-USCommunityServer 2.1 SP2 (Build: 61129.1)For the Better Developer: When indexes are not enoughhttp://sqlblog.com/blogs/davide_mauri/archive/2017/10/03/for-the-better-developer-when-indexes-are-not-enough.aspxTue, 03 Oct 2017 22:23:37 GMT21093a07-8b3d-42db-8cbf-3350fcbf5496:64096manowar<p>Another month, another session for the PASS Application Development VG. This time I will be both the host and the guest :), talking about something is very close to my interests and, I think, also a key point for any developer to have success in future of AI. Here’s the session title and abstract:</p> <blockquote> <p><strong>For the Better Developer: When indexes are not enough</strong></p> <p>If you want optimum performance in SQL Server, you have to use indexes. But what if you already implemented indexes and your solution is still slow or it doesn’t scale like you want? Or, if you're on Azure, it is just requiring too much resources, which in turns means just more money to be spent on it? You may have to rethink the way you write your queries. How you write your queries is directly related to how you approach and solve your business problems, and more often than not thinking outside the box is the way to unlock incredible performances. But what this exactly means in a database? And how a developer can do that? In this session, you’ll see how using some lateral thinking and a set-based approach will open up a whole world of possibilities. Thanks to this demo intensive session, you'll never be the same after switching on this new mindset!</p> </blockquote> <p>registration is free via the usual link:</p> <p><a href="http://appdev.pass.org/">http://appdev.pass.org/</a></p> <p>Live event will take place on <strong>October 18th</strong>, and, again as usual, session will be recorded and made available on group YouTube channel couple of days after the live event.</p>Speaking @ PASS Summit 2017http://sqlblog.com/blogs/davide_mauri/archive/2017/07/24/speaking-pass-summit-2017.aspxMon, 24 Jul 2017 10:34:08 GMT21093a07-8b3d-42db-8cbf-3350fcbf5496:63685manowar<p>After years and years talking about Business Intelligence and Business Analytics, this year at PASS I’ll be speaking about Application Development and how to make the best use of the data platform that Microsoft created so far.</p> <p>I’ve started talking about the impedance mismatch at the beginning of my career and now, after <a href="https://medium.com/@mauridb/lets-start-again-86512919f40f">15 year of Business Intelligence, Big Data, Analytics, Data Warehousing</a>, I’m back talking about it again, but this time there is a new amazing approach to the problem: microORM.</p> <p>MicroORM are ORM that only take care of one thing: mapping database result-set to classes and nothing more. I love the idea because it allows developers and DBAs to leverage all the power of RDBMS whilst, at the same time, remove all the boring and error-prone plumbing code. As Van Halen said, it is just the “<a href="https://en.wikipedia.org/wiki/The_Best_of_Both_Worlds_(Van_Halen_album)">Best of Both Worlds</a>”.</p> <p>As a result, MicroORM are, in my opinion, just perfect in a Micro-Services scenario. They make things simple, but not simpler, while preserving performance and making a developer just more productive (give that he/she must know how to query a database, <a href="https://medium.com/sql-server-for-the-better-developer/know-your-data-base-affd6241bcac">something that is mandatory IMHO</a>).</p> <p>More specifically I’ll talking about Dapper.NET a microORM I’ve learned to love in the last years, and that I use everyday:</p> <blockquote> <p><strong><a href="http://www.pass.org/summit/2017/Sessions/ConferenceSessions.aspx#sid65896">Dapper: the microORM that will change your life </a></strong></p> <p>ORM or Stored Procedures? Code First or Database First? Ad-Hoc Queries? Impedance Mismatch? If you're a developer or you are a DBA working with developers you have heard all this terms at least once in your life…and usually in the middle of a strong discussion, debating about one or the other. Well, thanks to StackOverflow's Dapper, all these fights are finished. Dapper is a blazing fast microORM that allows developers to map SQL queries to classes automatically, leaving (and encouraging) the usage of stored procedures, parameterized statements and all the good stuff that SQL Server offers (JSON and TVP are supported too!) In this session I'll show how to use Dapper in your projects from the very basis to some more complex usages that will help you to create *really fast* applications without the burden of huge and complex ORMs. The days of Impedance Mismatch are finally over! </p> </blockquote> <p>See you at PASS 2017!</p>T-SQL Window Functionshttp://sqlblog.com/blogs/davide_mauri/archive/2017/07/10/t-sql-window-functions.aspxMon, 10 Jul 2017 16:13:50 GMT21093a07-8b3d-42db-8cbf-3350fcbf5496:63641manowar<p>I’ll soon post something on this, but let me tell you right here. If you don’t want AI to take you DEV/DBA/BI job you *need* to be smarter than AI (which is not AI at all right now, but let’s keep on playing the marketing game): one way to become smarter is to - guess! - use your brain and train it to think out of the box, practice <a href="https://en.wikipedia.org/wiki/Lateral_thinking"><em>lateral thinking</em></a><em>&#160;</em>and more in general do all the things that brute force and Machine Learning cannot do.</p> <p>Of course when you do that, you have to be supported by a language that allows you to exploit all such potential. SQL is one of those nice languages. So don’t miss Itzik Ben-Gan session on <strong>T-SQL Window Functions on July 13th</strong> for the Application Development Virtual Group:</p> <blockquote> <p><strong>T-SQL Window Functions</strong></p> <p><em><a href="https://twitter.com/itzikbengan">Itzik Ben-Gan</a></em></p> <p>T-SQL window functions allow you to perform data analysis calculations like aggregates, ranking, offset and more. When compared with alternative tools to achieve similar tasks like grouping, joining, using subqueries, window functions have several interesting advantages that allow you to solve your tasks often more elegantly and more efficiently. Furthermore, as it turns out, window functions can be used to solve a wide variety of T-SQL querying tasks well beyond their original intended use case, which is data analysis. This session introduces window functions and their evolution from SQL Server 2005 to SQL Server 2017, explains how they get optimized, and shows practical use cases.</p> </blockquote> <p>Registration via the usual link:</p> <p><a title="http://appdev.pass.org/" href="http://appdev.pass.org/">http://appdev.pass.org/</a></p> <p>Don’t miss it, no matter if you’re into SQL Server or not. This will be useful to everyone who works with databases that supports the standard <a href="https://en.wikipedia.org/wiki/SQL:2003">ANSI-SQL 2003</a> and after. This means, SQL Server, Azure SQL, of course, but also <a href="https://cwiki.apache.org/confluence/display/Hive/Home">Hive</a>, <a href="https://spark.apache.org/releases/spark-release-2-0-0.html">SparkQL</a>, <a href="https://www.postgresql.org/">Postgres</a> and <strike>MySQL</strike> (nope,sorry), <a href="https://mariadb.com/kb/en/mariadb/window-functions/">MariaDB</a></p>Getting Excited about my Practical Performance Monitoring Pre-Conhttp://sqlblog.com/blogs/andrew_kelly/archive/2017/07/02/getting-excited-about-my-practical-performance-monitoring-pre-con.aspxSun, 02 Jul 2017 19:43:00 GMT21093a07-8b3d-42db-8cbf-3350fcbf5496:63616Andrew Kelly<p>&#160;</p> <p>I was working on the demo’s for my <a href="http://itdevconnections.com/dc17/Public/SessionDetails.aspx?FromPage=Speakers.aspx&amp;SessionID=1018435&amp;nav=true&amp;Role=U%27" target="_blank">Practical Performance Monitoring</a> Pre-Con at this years <a href="http://itdevconnections.com/dc17/Public/enter.aspx" target="_blank">IT / Dev Connections</a> in San Francisco and I have to admit I got a little giddy<img class="wlEmoticon wlEmoticon-smile" style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;" alt="Smile" src="http://sqlblog.com/blogs/andrew_kelly/wlEmoticon-smile_13044AE4.png" />.&#160; The session is geared towards helping a DBA get started in monitoring their SQL Server Instances, especially when they don’t have the ability to buy a 3rd party utility. This doesn’t mean to imply that you have to be a SQL Server beginner to appreciate the session. I know lots of more experienced DBA’s who simply never had the time or training to get a handle on daily performance monitoring. That is where this shines and is one of the reasons I got giddy if you will. You see I use a lot of this code that I was prepping for the demos daily. In fact most if not all stemmed from real life needs. I try to concentrate on the aspects of monitoring that give the biggest bang for the buck and make a real difference in the average DBA’s daily chores. Hence the “Practical” part of the title for this session.&#160; I have been teaching and presenting for many years now but I still get excited with the thought of passing on my knowledge and experience with sessions like this. If any of you are in need of this type of training I am positive you won’t be disappointed with what you can walk away with. Like I said this is code and techniques I use every working day and I know you can immediately use it in your environment as well. I can’t wait and I hope to see you there.</p> <p>Andy Kelly</p>Logging wait stats over timehttp://sqlblog.com/blogs/tibor_karaszi/archive/2017/06/08/logging-wait-stats-over-time.aspxThu, 08 Jun 2017 14:32:00 GMT21093a07-8b3d-42db-8cbf-3350fcbf5496:63386TiborKaraszi<p>We all know how valuable wait statistics can be when doing performance analysis. One thing I feel is missing in SQL Server is a trail of various measures,&nbsp;for instance&nbsp;wait stats. I really wish Microsoft could include something in this area, which can be used as a baseline. I recently fount <a target="_blank" mce_href="https://blogs.msdn.microsoft.com/sql_server_team/sql-server-performance-baselining-reports-unleashed-for-enterprise-monitoring/" href="https://blogs.msdn.microsoft.com/sql_server_team/sql-server-performance-baselining-reports-unleashed-for-enterprise-monitoring/">this</a>, from the Tiger Team. It looks promising, but I haven't implemented it yet.</p><p>Anyhow, I have created&nbsp;a script that log wait stats over time. I keep a trail&nbsp;of logged value which is denser - for instance once per minute. And&nbsp;also a trail which is courser, for instance once per day.</p><p>The solution has a few tables and then you create a couple of Agent jobs. The logging and clean-up part is methinks pretty much done. The part that need more work is the analysis of the information. I.e., expect to find queries and&nbsp;views added. Suggestions are of course very welcome!</p><p>You find the stuff <a mce_href="http://karaszi.com/log-wait-stats-over-time" href="http://karaszi.com/log-wait-stats-over-time">here</a>.&nbsp;</p>Explaining Activity Monitorhttp://sqlblog.com/blogs/tibor_karaszi/archive/2017/02/16/explaining-activity-monitor.aspxThu, 16 Feb 2017 20:08:00 GMT21093a07-8b3d-42db-8cbf-3350fcbf5496:62684TiborKaraszi<p>This post is <strong>not</strong> about how to use the Activity Monitor (AM) tool in SQL Server Management Studio (SSMS) – there are loads of such posts written already. Also, it is not about dissing AM, you will find such posts as well.<br></p><p>What I want to do is to explain the information in AM, for instance what time span the information covers. I see lots of confusion about this, and incorrect assumptions can be made because of that. This aspect is typically not mentioned in other blog posts on AM that I have seen.<br></p><p>The SQL Server documentation is very vague on the topic. In fact, the most recent documentation article explaining the information in AM that I found is for SQL Server 2008 R2. And that documentation is at many places vague, or even flat out incorrect. For more recent versions of SQL Server, there’s not even an attempt to explain the information. (Please let me know if you find such official articles.)</p><p>I know that lots of people uses the Activity Monitor tool in SQL Server, especially the less experienced DBA. The more experienced DBA often uses other tools like Adam Machanic‘s sp_whoisactive (see&nbsp;<a title="http://whoisactive.com/ " href="http://whoisactive.com/" mce_href="http://whoisactive.com/ ">this</a> and <a title="http://sqlblog.com/tags/Who+is+Active/sp_5F00_whoisactive/default.aspx" href="http://sqlblog.com/tags/Who+is+Active/sp_5F00_whoisactive/default.aspx" mce_href="http://sqlblog.com/tags/Who+is+Active/sp_5F00_whoisactive/default.aspx">this</a>) , Brent Ozar’s <a title="https://www.brentozar.com/askbrent/" href="https://www.brentozar.com/askbrent/" mce_href="https://www.brentozar.com/askbrent/">sp_BlitzFirst</a>, etc.</p><p>Say for instance that you had massive amount of I/O for one of your databases for the last day, up until a minute ago. I.e., the I/O load for the database varies a bit, but on average is very high. You look in AM which show this database as silent since you happened to have low I/O the last minute, and AM show some other database as being the one with high load.</p><p>So, we need to think about the time dimension here. AM does a refresh at certain intervals. By default it is every 10 seconds, but you can change that by right-clicking somewhere in AM and change in that context menu. Keep this in mind. It is important. We will refer to it as the most recent refresh interval, or snapshot.</p><p>I’m using SQL Server Management Studio (SSMS) 2016, and SQL Server 2016. It is possible that other version combination does other things. With the information in this blog post, you will be able to find and determine that for yourself. Please comment if you find important deviations, or perhaps just confirmations (like “SSMS 2012 does the same thing”).</p><p>I mainly used tracing to spy on the SQL submitted by AM.</p><p><b>The four top graphs:<br></b>(Or five, but there's no info in the right-most diagram for me – possibly it shows info for some feature that I’m not using in my current setup.)</p><blockquote style="margin-right:0px;" dir="ltr"><p><img width="212" height="127" style="width:212px;height:127px;" src="http://www.karaszi.com/SQLServer/misc/ActivityMonitor/PercProcessorTime.JPG">&nbsp;<br><b>“% Processor Time”</b> is picked up directly from the OS (using WMI, I believe). Most probably a Performance Monitor counter in the end.</p><p>&nbsp;<img width="218" height="131" style="width:218px;height:131px;" src="http://www.karaszi.com/SQLServer/misc/ActivityMonitor/DatabaseIO.JPG"><br><b>“Database I/O”</b> is the sum of I/O for all database files performed since the last snapshot. This is fine since we intuitively understand that, because we have the trail of prior snapshot values displayed in the graph. The information comes from sys.dm_io_virtual_file_stats, doing a SUM over num_of_bytes_read + num_of_bytes_written, converted to MB.</p><p><b><img width="216" height="132" style="width:216px;height:132px;" src="http://www.karaszi.com/SQLServer/misc/ActivityMonitor/BatchRequestsPerSec.JPG"><br>“Batch Requests/sec”</b> is the number of batches we have submitted to our SQL Server since the last snapshot. Again, this is pretty intuitive since we have a trail of snapshot values in the graph. The information is from the performance counter “Batch Requests/sec” picked up from sys.sysperfinfo (bad Microsoft, you should use sys.dm_os_performance_counters :-) ).</p><p><b><img width="215" height="131" style="width:215px;height:131px;" src="http://www.karaszi.com/SQLServer/misc/ActivityMonitor/WaitingTasks.JPG"><br>“Waiting Tasks”</b> show how many that are waiting for something (a lock to be released, for instance). This is not as straight-forward as the others. The information comes from sys.dm_os_wait_stats UNION ALL with sys.dm_os_waiting_tasks.</p><p>The values are compared to those from the prior snapshot. However, a higher weight in that calculation will be given to the prior snapshot values if you have a short refresh interval. Say that you have a 1-second refresh interval. Then only a weight of 9% is from the current interval and 91% is from the prior interval. Since the current interval value will become the prior value for the next snapshot, a “trail” is kept back in time with a diminishing weight the longer back in time you go.</p><p>If you refresh every 10 seconds, then current interval weight is 60% and previous interval weight is 40%. It pretty quickly approaches 100% for current snapshot the longer refresh interval you are using. Hats off to Microsoft for so clearly documenting this in the temporary stored procedures that AM is using. It is in the source code, all you need to do is to grab it in a trace and read it. The name of the procedure is #am_generate_waitstats, and it is created when you open the AM window in SSMS.</p><p>Note that not all wait types are represented here. See the section below named ‘The “Resource Waits” pane’ for more information. The “Waiting Tasks” diagram and the “Resource Waits” pane shares some T-SQL code.</p><p>&nbsp;</p></blockquote><p><b><img width="446" height="135" style="width:446px;height:135px;" src="http://www.karaszi.com/SQLServer/misc/ActivityMonitor/Processes.JPG"></b></p><p><b>The “Processes” pane</b><br>This is pretty straight forward so I won’t spend much time on it here. It shows information about the sessions you have at the moment the snapshot is produced. It uses a query joining DMVs such as sys.dm_exec_sessions, sys.dm_exec_requests, sys.dm_os_tasks, etc. Go grab the query in a trace and paste into a query window if you want to dig into it.</p><p>&nbsp;</p><p><img width="523" height="245" style="width:523px;height:245px;" src="http://www.karaszi.com/SQLServer/misc/ActivityMonitor/ResourceWaits.JPG">&nbsp;</p><p><b>The “Resource Waits” pane</b><br>The idea here is to show where SQL Server is waiting, “wait stats”.</p><p>It uses the same procedure as the “Waiting Tasks” diagram uses, #am_generate_waitstats, to get the information. See the above section for “Waiting Tasks” to understand the time dimension for this. For simplicity, we can say that it shows only wait stats for the past 30-60 seconds. This is important. Imagine that you had loads of a certain wait stats, but none just for the last minute. This pane can now fool you that you didn’t have any waits of that kind, just because you didn’t for the past minute. Note, though, that the “Cumulative Wait Time” column is the sum of wait in the group since SQL Server was re-started or since we last cleared the wait state (DBCC SQLPERF("sys.dm_os_wait_stats",CLEAR)).</p><p>In an attempt to be friendly, it will group and summarize wait stats into various groups. That would be fine if there were some documentation about which individual wait type is in each group. Also, some wait types are ignored. One of the ignored wait types is CXPACKET, another is THREADPOOL. </p><p>AM creates a table named #am_wait_types when you open the AM window, which it populates with various wait types and the group each wait stats is in. This table has a column named “ignore”. The two wait types I mentioned above has 1 in this “ignore” column. There are 35 rows which has 1 for the “ignore” column. To be fair, most are benign but the two which I immediately reacted on are the ones I mentioned above.</p><p>But hang on, how many rows do we have in this #am_wait_types table in total?&nbsp; The answer is 263. Are there more than 263 wait types in 2016? You bet! I did a select from sys.dm_os_wait_stats and I got 875 rows. So, 633 of the wait types in 2016 are not at all considered by AM. That of course begs the question whether I found any interesting wait types that aren’t in #am_wait_types? I didn’t go through them all, but I glanced only quickly and for instance SOS_SCHEDULER_YIELD caught my attention. If you want to go through them, then I highly recommend Paul Randal’s <a title="https://www.sqlskills.com/help/waits/" href="https://www.sqlskills.com/help/waits/" mce_href="https://www.sqlskills.com/help/waits/">wait types library</a>. If you find anything that stands out, then please post a comment. </p><p><font face="Times New Roman" size="3">
</font><span style="background:white;color:blue;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">SELECT</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> ws</span><span style="background:white;color:gray;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">.</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">wait_type </span><span style="background:white;color:blue;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">FROM</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> </span><span style="background:white;color:lime;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">sys</span><span style="background:white;color:gray;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">.</span><span style="background:white;color:lime;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">dm_os_wait_stats</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> </span><span style="background:white;color:blue;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">AS</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> ws<br></span><span style="background:white;color:blue;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">WHERE</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> ws</span><span style="background:white;color:gray;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">.</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">wait_type </span><span style="background:white;color:gray;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">NOT</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> </span><span style="background:white;color:gray;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">IN(<br></span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"><span style="mso-tab-count:1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="background:white;color:blue;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">SELECT</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> wt</span><span style="background:white;color:gray;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">.</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">wait_type </span><span style="background:white;color:blue;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">FROM</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> #am_wait_types </span><span style="background:white;color:blue;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">AS</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> wt </span><span style="background:white;color:blue;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">WHERE</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> wt</span><span style="background:white;color:gray;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">.</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">ignore
</span><span style="background:white;color:gray;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;">=</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"> 0<br></span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-ansi-language:EN-US;mso-bidi-font-family:Consolas;mso-highlight:white;"><span style="mso-tab-count:1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="background:white;color:gray;font-family:Consolas;font-size:9.5pt;mso-bidi-font-family:Consolas;mso-highlight:white;">)<br></span><span style="background:white;color:blue;font-family:Consolas;font-size:9.5pt;mso-bidi-font-family:Consolas;mso-highlight:white;">ORDER</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-bidi-font-family:Consolas;mso-highlight:white;"> </span><span style="background:white;color:blue;font-family:Consolas;font-size:9.5pt;mso-bidi-font-family:Consolas;mso-highlight:white;">BY</span><span style="background:white;color:black;font-family:Consolas;font-size:9.5pt;mso-bidi-font-family:Consolas;mso-highlight:white;"> wait_type</span></p><p>&nbsp;</p><p><img width="808" height="153" style="width:808px;height:153px;" src="http://www.karaszi.com/SQLServer/misc/ActivityMonitor/DataFileIO.JPG"></p><p><b>The “Data File I/O” pane</b><br>This shows I/O activity per database file since the last snapshot. Again, you could for instance have had lots of I/O for a database the last day, but if it was silent the past minute, then this dialog will potentially mislead you.</p><p>&nbsp;</p><p><img width="667" height="156" style="width:667px;height:156px;" src="http://www.karaszi.com/SQLServer/misc/ActivityMonitor/RecentExpensiveQueries.JPG"></p><p><b>The “Recent Expensive Queries” pane</b><br>This shows the most expensive queries, based on what column you sort on, executed since the last snapshot. If you have, say, a 10 second snapshot interval, you will only see the queries executed during these 10 seconds. AM uses a procedure named #am_get_querystats to collect the information. There are a few things going on inside this procedure, but at the most basic level, it uses sys.dm_exec_query_stats and sys.dm_exec_requests to get queries from cache and currently executing queries. It then does some processing and store the result in temp tables so we later can sort on different columns depending on what metric we are interested in. I suggest that you spend some time with the source code if you want to dig deeper.</p><p>&nbsp;</p><p><img width="640" height="143" style="width:640px;height:143px;" src="http://www.karaszi.com/SQLServer/misc/ActivityMonitor/ActiveExpensiveQueries.JPG"></p><p><b>The “Active Expensive Queries” pane</b><br>This is very straight forward. It executes a query which uses sys.dm_exec_requests joined to a few other DMVs.</p><p><br><b>How to dig deeper</b><br>I thought about including snippets of AM’s source code, the list of wait stats grouping etc here. But I decided against that. It would litter this post, and the code might differ between releases and builds of SSMS. So, if you are interested in digging deeper, fire up your favorite trace tool (Extended Events, Profiler, Server-side trace, …) and catch the SQL submitted by AM. </p><p>When you open the AM window, it executes a few batches that creates procedures and tables that it will later use for each refresh interval. Here are the ones that I found:</p><ul><li>The table #am_wait_types, which contains the wait types that AM bothers about, along with the grouping and which of those that are ignored. This is the one you want to investigate to see which wait types that are ignores by AM; either having 1 in the “ignore” column, or by not being in that table in the first place. Match against sys.dm_os_wait_stats.</li><li>The procedure #am_generate_waitstats which collects wait stats with some trail back in time, as explained above.</li><li>The table #am_dbfileio in which file I/O stats is stored.</li><li>The tables #am_request_countand and #am_fingerprint_stats_snapshots, used for query statistics.</li><li>The procedure #am_get_querystats, which collects and stores the query statistics.</li></ul><p>At each refresh interval, you see 4 T-SQL batches submitted for the top 3 graphs that are T-SQL based (ignoring the “dead” graph that I have in SSMS 2016, and also ignoring “% Processor Time” since it is WMI-based). </p><p>If you have expanded the “Processes” pane, you also see a batch that collects that information at every refresh interval.</p><p>If you have expanded the “Resource waits” pane, you also see a batch that does a SELECT from the #am_resource_mon_snap table at every refresh interval, with grouping and SUM based on resource type.</p><p>If you have expanded the “Data File I/O” pane, you also see a batch that collects that information at every refresh interval.</p><p>If you have expanded the “Recent Expensive Queries” pane, you also see a batch that executes the #am_get_querystats procedure to collects that information. It is executed at refresh intervals, but not necessarily at every refresh interval. Check the source code for the procedure and you see that SM will execute this no more frequently than every 15 seconds.</p><p>If you have expanded the “Active Expensive Queries” pane, you also see a batch that executes a query to collects that information. It seems to be limited so it doesn’t execute more frequently than every 5 seconds (even with a shorter refresh interval).</p><p><strong>The bottom line<br></strong>As always, with understanding of the data we see, we have a chance to make information out of it.&nbsp;The Activity Monitor certainly has its quirks, but if you do feel like using a GUI for these type of things, I hope that you are better equipped now to interpret what it is you are seeing. Personally, I find “Resource Waits”, “Data File I/O” and “Recent Expensive Queries” less useful because of the time dimension handling. As for expensive queries, IMO nothing beats the Query Store in SQL Server 2016.</p>SQL Nexus 5.5.0.1http://sqlblog.com/blogs/andrew_kelly/archive/2016/11/20/sql-nexus-5-5-0-1.aspxMon, 21 Nov 2016 03:24:00 GMT21093a07-8b3d-42db-8cbf-3350fcbf5496:62193Andrew Kelly<p>&#160;</p> <p>The SQL Nexus set of utilities are some of the most under utilized tools available to the SQL Server community. I used and touted the RML utility for many years to help people analyze trace information very fast and easily. Eventually XE traces were added to the list along with much more.&#160; This <a href="https://blogs.msdn.microsoft.com/psssql/2016/11/20/sql-nexus-5-5-0-1-was-released/" target="_blank">blog post link</a> will give you a pretty good overview of what you can expect along with the the <a href="https://sqlnexus.codeplex.com/" target="_blank">codeplex download</a> page which also goes into some details. The included documentation has always been top notch in my opinion. If you have never took a look at these utilities I highly recommend doing so. As always, enjoy.</p> <p>Andy</p>Misconceptions on parameter sniffinghttp://sqlblog.com/blogs/hugo_kornelis/archive/2016/11/02/misconceptions-on-parameter-sniffing.aspxThu, 03 Nov 2016 01:55:00 GMT21093a07-8b3d-42db-8cbf-3350fcbf5496:62117Hugo Kornelis<p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">In </font></font></span><font style="font-size:12pt;"><a><span style="mso-ansi-language:en-gb;"><font color="#0000ff" face="Times New Roman">my previous post</font></span></a></font><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">, I explained the basic of parameter sniffing, and then built on that to explain the lesser known mechanics of variable sniffing and cardinality sniffing. However, I also sneakily inserted a few comments on misconceptions about the performance impact of parameter sniffing, with the promise to explain in more detail later. Well … it is later now, so here is the promised explanation!</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:13.5pt;">Parameter sniffing’s bad rep</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Lots of people in the SQL Server field will claim that parameter sniffing is a bad feature. That is not the case. Just think about it for a moment – the feature has been in the product since at least SQL Server 2005, probably even earlier. If it were truly a bad feature, then surely just removing the feature would have been a very simple way to improve the product. But Microsoft has done no such thing, and whatever horror stories on Microsoft you believe, they have not become one of the world’s biggest companies by foolishly refusing to take opportunities to improve their software for almost no investment.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">However, there is no denying that parameter sniffing <i style="mso-bidi-font-style:normal;">can</i> cause terrible performance issues. I will explain by using a slightly modified version of the example that my good friend </font></font></span><font style="font-size:12pt;"><a><span style="mso-ansi-language:en-gb;"><font color="#0000ff" face="Times New Roman">Grant Fritchey</font></span></a></font><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;"> likes to use. (Note that I used the AdventureWorks2012 sample database, but other versions of AdventureWorks should expose the same behaviour).</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">CREATE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">INDEX</font></span> ix_Addess_City</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">ON</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> Person<span style="color:;"><font color="#808080">.</font></span>[Address]<span style="color:;"><font color="#0000ff"> </font></span><span style="color:;"><font color="#808080">(</font></span>City</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">);</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">CREATE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">PROC</font></span> dbo<span style="color:;"><font color="#808080">.</font></span>GetAddressByCity</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font style="font-size:9.5pt;">@City <span style="color:;"><font color="#0000ff">nvarchar</font></span><span style="color:;"><font color="#808080">(</font></span>30</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">)</font></span></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">AS</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>a<span style="color:;"><font color="#808080">.</font></span>AddressID</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">,</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font style="font-size:9.5pt;">a<span style="color:;"><font color="#808080">.</font></span>AddressLine1</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">,</font></span></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font style="font-size:9.5pt;">a<span style="color:;"><font color="#808080">.</font></span>AddressLine2</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">,</font></span></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font style="font-size:9.5pt;">a<span style="color:;"><font color="#808080">.</font></span>City</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">,</font></span></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font style="font-size:9.5pt;">sp<span style="color:;"><font color="#808080">.</font></span>[Name] <span style="color:;"><font color="#0000ff">AS</font></span> StateProvinceName</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">,</font></span></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font style="font-size:9.5pt;">a<span style="color:;"><font color="#808080">.</font></span>PostalCode</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Person<span style="color:;"><font color="#808080">.</font></span>[Address] <span style="color:;"><font color="#0000ff">AS</font></span> a</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#808080"><font style="font-size:9.5pt;">INNER</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#808080">JOIN</font></span><span style="mso-spacerun:yes;">&nbsp; </span>Person<span style="color:;"><font color="#808080">.</font></span>StateProvince <span style="color:;"><font color="#0000ff">AS</font></span> sp</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font style="font-size:9.5pt;"><span style="color:;"><font color="#0000ff">ON</font></span><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>sp<span style="color:;"><font color="#808080">.</font></span>StateProvinceID <span style="color:;"><font color="#808080">=</font></span> a<span style="color:;"><font color="#808080">.</font></span>StateProvinceID</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">WHERE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>a<span style="color:;"><font color="#808080">.</font></span>City <span style="color:;"><font color="#808080">=</font></span> @City</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> dbo<span style="color:;"><font color="#808080">.</font></span>GetAddressByCity<span style="color:;"><font color="#0000ff"> </font></span>@City <span style="color:;"><font color="#808080">=</font></span> <span style="color:;"><font color="#ff0000">'Mentor'</font></span></font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SET</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">STATISTICS</font></span> <span style="color:;"><font color="#0000ff">IO</font></span> <span style="color:;"><font color="#0000ff">ON</font></span></font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> dbo<span style="color:;"><font color="#808080">.</font></span>GetAddressByCity<span style="color:;"><font color="#0000ff"> </font></span>@City <span style="color:;"><font color="#808080">=</font></span> <span style="color:;"><font color="#ff0000">'London'</font></span></font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SET</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">STATISTICS</font></span> <span style="color:;"><font color="#0000ff">IO</font></span> <span style="color:;"><font color="#0000ff">OFF</font></span></font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">DROP</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">PROC</font></span> dbo<span style="color:;"><font color="#808080">.</font></span>GetAddressByCity</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">DROP</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">INDEX</font></span> ix_Addess_City <span style="color:;"><font color="#0000ff">ON</font></span> Person<span style="color:;"><font color="#808080">.</font></span>[Address]</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Since the tables used in this example are fairly small, you will not actually notice any slowness. But if you look at the output generated by the SET STATISTICS IO option, you should see that there actually is a serious issue with this query. The second execution of the stored procedure takes 871 logical reads on the <i style="mso-bidi-font-style:normal;">Address</i> table, and 868 logical reads on the <i style="mso-bidi-font-style:normal;">StateProvince</i> table – insane numbers when you realize that the entire <i style="mso-bidi-font-style:normal;">Address</i> table is stored in just 216 pages, and <i style="mso-bidi-font-style:normal;">StateProvince</i> is even just 3 pages in size!</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">If you look at the execution plan, you will start to see why this is the case:</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-no-proof:yes;"></span><span style="mso-ansi-language:en-gb;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><a mce_href="http://sqlblog.com/blogs/hugo_kornelis/image_1B9F4D29.png" href="http://sqlblog.com/blogs/hugo_kornelis/image_1B9F4D29.png"><img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="image" src="http://sqlblog.com/blogs/hugo_kornelis/image_thumb_53055E57.png" height="213" border="0" width="609"></a></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;">&nbsp;</span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">An index seek is used to find <i style="mso-bidi-font-style:normal;">Address</i> rows matching the supplied parameter, which are then retrieved in full by the index seek, and then a clustered index seek in <i style="mso-bidi-font-style:normal;">StateProvince</i> is used to do the join. This type of plan is very good when the filter is expected to be very selective, which is the case for Mentor (with just one matching row), the value that was sniffed when the plan was compiled during the first call. For the second call, the same plan was then reused, but because the filter on London (with 435 matches) is far less selective the plan is now actually quite bad.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The biggest issue with such cases of bad performance caused by parameter sniffing is that they tend to be hard to troubleshoot. The performance of the GetAddressByCity stored procedure depends on the value that happens to be passed in on the first execution after the previous plan cache entry was invalidated or removed. But most of the common reasons for plan invalidation are beyond our control, so to the user of the system it can appear that the performance of this procedure changes at “random” moments. And obviously, once the DBA is ready to respond to the ticket a new recompile might already have occurred and the performance might be find again.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Another very common cause for bad parameter sniffing is the use of a single generic procedure to return rows based on a series of parameters that are all considered optional for the search. A simple example would be a procedure dbo.GetAddressByCityOrPostalCode that uses two parameters @City and @PostalCode, and that has a query with a WHERE clause such as “WHERE (City = @City OR @City IS NULL) AND (PostalCode = @ PostalCode OR @ PostalCode IS NULL)”. When this stored procedure is first called with @ PostalCode = ‘W10 6BL’ and @City = NULL, a plan will be compiled and stored in plan cache that is optimal for this combination of parameters. If a later execution uses @PostalCode = NULL and @City = ‘Mentor’, then the results returned will still be correct but the performance will likely be bad, because the query is still executed using a plan that is optimized for a search by PostalCode only. For instance, it could use a plan that uses an Index Seek in an index on PostalCode to find ows matching the second part of the WHERE (which would find all rows on the second execution), then use a Key Lookup to find the rest of the data and then filter down on City = ‘Mentor’. For this type of stored procedure you really want multiple plans stored and the one that is best for the current parameters used, but that’s just not how SQL Server works.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Bad parameter sniffing in a production system can be hard to troubleshoot. The problem only materializes when a procedure that is susceptible to bad parameter sniffing is recompiled, <b style="mso-bidi-font-weight:normal;">and</b> the parameter values sniffed during that recompile happen to cause a plan that is bad for many other values. This is especially rare when the issue is caused by <span style="mso-spacerun:yes;">&nbsp;</span>skewed data distribution, because the really bad performance tends to be caused by a recompile for a rare outlier value, and these are not often used anyway. However, when it does hit you, it often hits you hard. When I see a database application that usually performs well but that at unexpected and unreproducible moments suddenly starts to perform bad (and then sometimes reverts to good performance later, again for no apparent reason), I always have bad parameter sniffing high on my list of likely root causes. The seemingly random switch from good to bad performance can be due to a recompile with a value that causes a bad plan. These occur at semi random moments because there are lots of reasons that can trigger a recompile (metadata change, (auto) update of statistics, memory pressure), and some of them are beyond our control.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:13.5pt;">The fanboys (and girls) are wrong</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Many of the experts in the SQL Server community try to combat the misconception that parameter sniffing is bad. But they unfortunately use the wrong arguments. They say that yes, there are cases of “bad” parameter sniffing that you will have to work around (which is indeed correct), but they then also claim that apart from these exceptions parameter sniffing is “usually” or even “always” good. I have heard and read such claims from some very smart and experienced people that I personally hold in high esteem, such as </font></font></span><font style="font-size:12pt;"><a><span style="mso-ansi-language:en-gb;"><font color="#0000ff" face="Times New Roman">Brent Ozar</font></span></a><span style="mso-ansi-language:en-gb;"><font face="Times New Roman">, Grant Fritchey, </font></span><a><span style="mso-ansi-language:en-gb;"><font color="#0000ff" face="Times New Roman">Gail Shaw</font></span></a></font><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">, and many others. And I myself have also held and spread this belief for a long time. Until recently when I was trying to find a few examples to actually illustrate the benefit of parameter sniffing – and failed to find any!</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">I then realized that from a parameter sniffing point of view, there are just two types of queries: those that are affected by parameter sniffing and those that are not. A lot of queries fall in the “not affected” category. I already gave some examples above:</font></font></span></p> <p class="MsoListParagraphCxSpFirst" style="list-style-type:disc;margin:0cm 0cm 0pt 36pt;text-indent:-18pt;mso-list:l0 level1 lfo1;" align="left"><font face="Times New Roman"><span style="mso-ansi-language:en-gb;"><span style="mso-list:ignore;"><font style="font-size:12pt;">1.</font><span style="font-family:;line-height:normal;"><font style="font-size:7pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span></span><span style="mso-ansi-language:en-gb;"><font style="font-size:12pt;">If a query filters on the primary key, the estimated rowcount when based on a sniffed value will be 1, but the estimated rowcount for the same query without sniffing (eg when using it as an ad hoc query with a variable) will also be 1 – so we’d get the same plan without sniffing as we do with sniffing.</font></span></font></p> <p class="MsoListParagraphCxSpLast" style="list-style-type:disc;margin:0cm 0cm 0pt 36pt;text-indent:-18pt;mso-list:l0 level1 lfo1;" align="left"><font face="Times New Roman"><span style="mso-ansi-language:en-gb;"><span style="mso-list:ignore;"><font style="font-size:12pt;">2.</font><span style="font-family:;line-height:normal;"><font style="font-size:7pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span></span><span style="mso-ansi-language:en-gb;"><font style="font-size:12pt;">If a query filters on a key with a fairly even data distribution, for instance with every value occurring somewhere between 90 and 110 times, then the estimate for a sniffed value can be any value between 90 and 110, and the estimate that we would get without sniffing, based on the average number of rows per value, would probably be around 100. It is extremely unlikely that such small changes in the estimate would cause a big difference in the execution plan. And in the rare cases where they do have an effect, see the below discussion on queries that <b style="mso-bidi-font-weight:normal;"><i style="mso-bidi-font-style:normal;">are</i></b> affected.</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The only way for a query to fall in the “affected” category is when the column has a skewed data distribution. (Or, rare, to have values at a frequency around the threshold value between two alternative plans). In that case, there will be at least two values (A and B) for which a different plan is optimal. And here’s the rub. When the value A is sniffed, the plan is cached, and the procedure is then executed with B, the cached plan will be sub-optimal for that value. And vice versa. So the parameter sniffing in this case will always be bad. (You might argue that it is possible that the plan for A and the plan for B might both be better than the plan for the generic average rows per value; I’d have to agree that in theory this might be possible but I have never ran into, nor been able to construct, such a query).</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:13.5pt;">Good parameter sniffing</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Now that I have shown how parameter sniffing is usually irrelevant and sometimes bad, you might wonder why the feature exists at all. The answer is that there are <b style="mso-bidi-font-weight:normal;">some</b> query patterns where parameter sniffing does actually help – and one of them is common enough that I would never recommend removing this feature from the product.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Lots of tables in lots of databases collect data over time. Orders keep being added in sales systems, banks keep processing transactions, and sensor data continues to poor into a table of readings. Those tables almost always have a column that timestamps the row (e.g. OrderDate, TransactionDate, MeasurementDate). And you will often find stored procedures that allow the user to select a recent subset of data by passing in a @ThresholdDate parameter – so that the results can be limited to e.g. the last hour, the last week, or the last 15 days. So the query in the stored procedure will filter on for instance </font></font></span><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;mso-bidi-font-size:9.5pt;"><font color="#0000ff"><font style="font-size:11pt;">WHERE</font></font></span><span style="font-family:;mso-ansi-language:en-us;mso-bidi-font-size:9.5pt;"><font style="font-size:11pt;"> OrderDate <span style="color:;"><font color="#808080">&gt;=</font></span> @ThresholdDate</font></span></font><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">.</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">This is the type of stored procedure that will usually benefit hugely from parameter sniffing. The predicate uses inequality. Without sniffing the value, that type of filter is one of the hardest to get right for the cardinality estimator – the value can be November 3<sup>rd</sup>, 1848, or the Year 2525, or anything in between – and so the number of matching rows can be anything from the entire table to nothing. The cardinality estimator simply uses an estimate of 30% matching rows for this case. If the stored procedure is typically called to fetch just the last few days of data out of a table containing eight years of history, then that estimate is going to be horribly wrong.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">This is one case where parameter sniffing really shines. It does not matter whether the sniffed value will be for a one-hour period, a one-day period, or a two-week period; in all these cases the plan based on that value will probably be the same, and definitely better than the plan you’d get for a 30% estimate. And if the cached plan is for two weeks and you next run the query for one hour, you’d still get the better performance. This single case is so common, and can have such huge impact on performance, that this use case on itself is already sufficient for me to defend the process of parameter sniffing – in spite of the occasions where it hurts, and the many cases where it’s irrelevant.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Another case of good parameter sniffing, far more esoteric, is if you have just the right combination of both a skewed data distribution and a skewed query pattern. Let’s return to Grant Fritchey’s example based on cities. This data distribution is skewed because there simply are far more people living in a city such as New York or Tokyo then there are in small villages such as </font></font></span><font style="font-size:12pt;"><a><span style="mso-ansi-language:en-gb;"><font color="#0000ff" face="Times New Roman">Hum</font></span></a><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"> or </font></span><a><span style="mso-ansi-language:en-gb;"><font color="#0000ff" face="Times New Roman">Adamstown</font></span></a></font><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">, so a stored procedure that filters on City tends to be subject to bad parameter sniffing. But what if you are working for a university and the researchers are working on a project involving only the inhabitants of very small villages? In that case, when the optimizer sniffs a value it will always be a small village and only a few rows will be returned, and again the plan based on any possible sniffed value is always going to be better for every value that is typically based, then a non-sniffed plan would be.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-us;"><font face="Times New Roman"><font style="font-size:13.5pt;">When good turns bad</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">You have to be aware, though, that good parameter sniffing, bad parameter sniffing, and irrelevant parameter sniffing, are all the same mechanism. The parameter sniffing remains the same, it’s the circumstances that make it go good or bad. And that’s something to keep in mind especially with code that relies on good parameter sniffing.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Let’s look once more at the Orders table with eight years of history, that is only ever queried for the most recent day, week or two week period. What happens if, one day, someone does actually submit a report to do some trend analysis on the last 5 years? The best and most likely result, in this case, would be that the cached plan, based on a previously sniffed parameter for a short period, is used. In that case, the report would be unbearably slow – the plan for the short period probably involves Nested Loop joins and Index Seeks, and running a few billion rows through that can take hours, or even days. The submitter of that query would suffer from bad parameter sniffing. But a worse scenario is also possible. It the previous plan has just been invalidated, a new plan will be created based on a sniffed value of five years ago, and now the plan would probably change to use scans. All other calls to the stored procedure will now start to use this plan as well, so that all those requests for short-term periods now run longer. The increased number of table scans will also start to affect overall system performance. The buffer cache fills up whenever the table is scanned so all other activity on the system has to reread from disk instead of run from cache. In short, the overall performance of the system as a whole would slow down, and it might take a long time to find the actual cause – and all that time, you would be losing sales because the web shop is now too slow for your impatient customers.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Even in a “good parameter sniffing” scenario, you should still be aware of the potential of bad parameter sniffing occurring, and take appropriate action to try to prevent it.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:13.5pt;">Dealing with bad parameter sniffing</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">If parameter sniffing is sometimes good, sometimes bad, and most often irrelevant, then the obvious question is: “how can I get the good without having to accept the bad as well”? And the good news is that this is possible. There are a lot of ways that allow you to deal with parameter sniffing, and I will briefly describe the options. (Note that most of them are described in much more detail elsewhere on the internet).</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The most brutal way of preventing bad parameter sniffing is to disable it completely. I do not like this method. To me, it sounds like torching down your house to prevent it from being burgled. But if you insist, you can: activating trace flag 4136 will disable <b style="mso-bidi-font-weight:normal;">all</b> parameter sniffing (good, bad, and irrelevant) on the entire instance. And yes, </font></font></span><font style="font-size:12pt;"><a><span style="mso-ansi-language:en-gb;"><font color="#0000ff" face="Times New Roman">it is documented and supported</font></span></a></font><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">A popular technique that is mostly found in old articles is to use local variables – this used to be one of the best options before SQL Server 2008. Declare a variable in the stored procedure for each parameter, assign it the value of the parameter, and then use that variable instead of the parameter in the rest of the code. The result is that SQL Server has to optimize the queries based on the variable, which it cannot sniff, so you always get a plan based on the generic data distribution rather than any sniffed value. I recently saw a recommendation somewhere to always do this for every parameter in every stored procedure – which has the same effect as using trace flag 4136, but with a lot more work. Seeing that recommendation was one of the things that triggered me to write this post. If you still need to support SQL Server 2005 or older, and if you only use it for specific parameters in specific stored procedures that are known or expected to get bad parameter sniffing, then I guess that using the local variable method can be okay. Using it in newer versions, or using it as a generic guideline for all parameters and stored procedure, is not correct.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Times New Roman"><span style="mso-ansi-language:en-gb;"><font style="font-size:12pt;">Since SQL Server 2008, we can use OPTION (OPTIMIZE FOR (@parameter UNKNOWN)) to force SQL Server to disregard any sniffed</font></span><span style="mso-ansi-language:en-us;"><font style="font-size:12pt;"> value and optimize the query as if the value for @parameter is not known. This has the same effect as using a local variable, except it does away with the extra overhead and you can limit it to just a single query in a multi-statement stored procedure. For that reason, I prefer this method over local variables. This method works very well in situations where the plan based on generic statistics is good enough for all possible cases. These tend to be cases where irrelevant and bad parameter sniffing can occur. In situations with good parameter sniffing, the generic plan you get with this option tends to be not good enough.</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="mso-ansi-language:en-us;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="mso-ansi-language:en-us;"><font face="Times New Roman"><font style="font-size:12pt;">Already since SQL Server 2005, you could use OPTION (OPTIMIZE FOR (@parameter_name = 'value')) to force SQL Server to optimize as if the value provided was sniffed. The risk of this method is that people tend to forget to maintain the value in the hint. For example in the case of retrieving the latest rows from the Orders table, this hint with a value of October 20, 2016 might work very well at this time – but if I forget to regularly update the code with a newer value, then that same hint will actually start to hurt performance in a terrible way after a few years, a year, or perhaps already after a few months. (And unfortunately, I have seen code in similar situations where a hint like this, for a datetime column, had not been changed for over three years!)</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="mso-ansi-language:en-us;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="mso-ansi-language:en-us;"><font face="Times New Roman"><font style="font-size:12pt;">Perhaps the best solution, depending on scenario, is to use multiple stored procedures, with one master to determine which one to execute. This can work for scenarios such as the Orders table (with one procedure to search in only recent data and another to search for longer time periods, and a master calling the right one), or for generic search procedures with a limited number of possibilities (with two optional search arguments you have four possible combinations and you can create four procedures; with five parameters you have 32 possible combinations and you do not want to create that many almost similar procedures – but you could check how many combinations are actually really used). It will not work in situations with skewed data, unless you happen to know all the outlier values.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="mso-ansi-language:en-us;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Times New Roman"><span style="mso-ansi-language:en-us;"><font style="font-size:12pt;">Another possible solution that works especially well for the optional search case is to use OPTION (RECOMPILE). As shown in</font></span><font style="font-size:12pt;"><span style="mso-ansi-language:en-gb;"> </span></font><span style="mso-ansi-language:en-gb;"><font style="font-size:12pt;">my previous post, this enables SQL Server to sniff the variable. And since this is a different process (because the optimizer does not have to cater for later reuse of the same plan with different values), this can give you tremendous benefits, even up to the optimizer removing entire joins from the plan if they are not needed for the current set of values. But there is a price to be paid: every time the stored procedure executes the query has to be compiled, which is a relatively expensive process. Depending on how often the procedure executes and how complex the query is, just the CPU and memory cost of the recompilations could cause serious issues to the overall performance of your server. My recommendation for this hint is to definitely use it where it makes sense, and equally definitely not use it anywhere else.</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">And finally, specifically for the procedure with optional search arguments, you could change the stored procedure to use dynamic SQL. This can be very dangerous when not done appropriately, but if you really know what you are doing it can be a viable alternative. You would have to construct a query string that contains only the predicates (and preferably also only the joins) that are needed based on the parameters passed it. You should not hardcode the parameter values themselves in the query string, nor allow any other form of user input to find its way in the parameter string. So the conditions in the dynamically generated query string would still be of the form WHERE Column1 = @Param1 AND Column3 = @Param3 (if only @Param1 and @Param3 have a value), and you should then use sp_executesql to execute the SQL and pass in the correct parameter values. For the parameter sniffing process, using sp_executesql is exactly the same as calling a stored procedure, but now with the query string instead of the procedure name as the “owner” of the plan. The values will be sniffed, a plan will be created and stored in cache, and the plan will be reused if the same query string is executed again – which in this case is okay, because that means the same combination of set and not set search parameters was used. For a stored procedure with five optional parameters, this might eventually result in all 32 possible permutations of the query being in the plan cache with a plan that is optimal for that permutation. But without you having to write all 32 possible versions of the query. However, be aware of the danger of SQL injection, and be aware that there may be issues with permission settings if you use dynamic SQL. I recommend Erland Sommmarskog’s excellent articles on </font></font></span><font style="font-size:12pt;"><a><span style="mso-ansi-language:en-gb;"><font color="#0000ff" face="Times New Roman">dynamic search conditions</font></span></a><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"> and on using </font></span><a><span style="mso-ansi-language:en-gb;"><font color="#0000ff" face="Times New Roman">dynamic SQL</font></span></a></font><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;"> if you consider using this method in your production code.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:13.5pt;">How about the other sniffings?</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">In my previous post, I described three forms of sniffing. In this post on good, bad, or irrelevant, I have so far only focused on parameter sniffing (which includes, as briefly mentioned above, the use of sp_executesql). So what about variable sniffing and cardinality sniffing?</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">To start with the latter: since cardinality sniffing is really just a special case of parameter sniffing, all I wrote above applies equally to cardinality sniffing. It can be good (in some cases), it can be bad (in other cases), and it will in most cases probably have no impact. When it is bad, then OPTION (RECOMPILE) is probably going to be your only useful instrument, and if that causes too much compilation overhead you might have to rearchitect your solution to avoid this problem. If you are in charge of a database that uses table-valued parameters, and after reading this post you realize that you are benefiting or suffering from cardinality sniffing, then I’d love to hear from you in the comments section!</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">For variable sniffing, none of the above applies. Since variable sniffing only occurs when you use OPTION (RECOMPILE), the plan will always be optimized for the current values, and it will never be reused. There is no possibility at all of bad variable sniffing happening, since the whole concept of bad sniffing is that a plan created for one value is reused for another value, which simply never happens with variable sniffing. In other words, variable sniffing will only ever be irrelevant or good, never bad – but it will also always be associated with the cost of OPTION (RECOMPILE), since that is the only condition that triggers it.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:13.5pt;">Conclusion</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">In the previous post, I described three forms of sniffing: the relatively well-known parameter sniffing, the lesser known variable sniffing, and the hitherto undocumented cardinality sniffing. In this post I tried to prove that both the doomsayers who claim that parameter sniffing is the Absolute Evil (TM), and the fanboys who appear to be in total love with parameter sniffing, are incorrect.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Parameter sniffing is actually usually totally irrelevant. But it still has a reason to exist, because in at least one of the cases where it does make a difference, it can provide a huge performance benefit. That does mean, though, that we will also have to accept a few cases where it can hurt.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Because the pain caused by bad parameter sniffing can be immense, I also walked through some of the more common fixes for these problems, describing their benefit and cost and explaining when you would or would not use them. I then also explained how bad, good, and irrelevant sniffing applies to variable and cardinality sniffing.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">I hope that these posts help you understand what sniffing is, how it can help or hurt, and how you can fix the latter without losing the former.</font></font></span></p>The sniffing databasehttp://sqlblog.com/blogs/hugo_kornelis/archive/2016/10/23/the-sniffing-database.aspxSun, 23 Oct 2016 23:28:00 GMT21093a07-8b3d-42db-8cbf-3350fcbf5496:62057Hugo Kornelis<p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Your SQL Server instances, like people with hay fever that forget to take their antihistamines during summer, is sniffing all the time. Sniffing is a trick employed by the optimizer in an attempt to give you better execution plans.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The most common form of sniffing is parameter sniffing. Many people know about parameter sniffing, but there are a lot of misconceptions about this subject. I have heard people describe parameter sniffing as a bad thing, and I know people who claim that parameter sniffing is mostly good with some exceptions that they then call “bad parameter sniffing”. Neither of these statements is true; in reality parameter sniffing (and the other forms of sniffing) are sometimes good, sometimes bad, and very often irrelevant. I will explain this in more detail in a later post – this post focuses on explaining what parameter sniffing actually is, and on what other forms of sniffing exist.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Yes, other forms of sniffing. Under the right conditions, SQL Server will also sniff variables and cardinalities. Most SQL Server developers and DBAs appear to be blissfully unaware of variable sniffing, and the few speakers and authors that do mention it tend to get it wrong. And cardinality sniffing is, as far as I know, completely undocumented. I have mentioned it a few times in some of my presentations, but never written about it – and I have never seen or heard anyone else describe this unique type of sniffing.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:13.5pt;">Parameter sniffing explained</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">To understand parameter sniffing, you have to know a bit about how SQL Server compiles queries into execution plans. When a query batch is submitted (either through an ad-hoc query tool such as Management Studio or the sqlcmd utility, or submitted from a client application through e.g. the ADO.Net library or JDBC), SQL Server will first try to avoid the (expensive) compilation process: it checks the plan cache to see if the same plan has been executed before and the plan is available. If that is not the case, then SQL Server will parse the entire batch, compile execution plans for each of the queries in the plan, store them in the plan cache. After that, all of the plans for the batch (either taken from the plan cache, or compiled, stored in the plan cache and then taken from it), are executed, in sequence or out of sequence as dictated by control-of-flow logic in the batch.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">While compiling the query, the optimizer uses statistics about the data in the tables to estimate how many rows will satisfy any given condition. A condition such as “WHERE Age = 42” on its own is pretty broad. When you understand the data it operates on, your perception of the condition will change: in a database on men in a mid-life crisis, odds are that a rather high percentage of the rows will match; the same condition in the student database of a community college should generate at most a handful of hits. This reflects in the statistics that the optimizer uses, so the same query condition can result in different plans depending on the data distribution.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">When the condition uses a variable (e.g. “WHERE Age = @Age”), then SQL Server cannot use the statistics in the same way. When the query is optimized, the optimizer knows the <i style="mso-bidi-font-style:normal;">data type</i> of the variable (because the parser has processed the DECLARE statement), but not the <i style="mso-bidi-font-style:normal;">value</i>, because it has not been assigned yet; the assignment occurs when the batch executes, after the optimization process. The optimize will still use some statistics, but not for a specific age; instead it looks at the number of distinct values used and assumes that the data is evenly distributed. So for a kindergarten database, the number of distinct values for Age would probably be three (5, 6, and 7), and the optimizer would assume 33% matching rows for any value of @Age passed in; for the US census database that same Age column would have over 100 distinct values, and the optimizer would estimate that less than 1% of the rows will match the condition for any value of @Age.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">A parameter looks for most purposes exactly like a regular variable. The difference is that a parameter is declared in the header of a separately executable code unit: a stored procedure, scalar user-defined function, or multi-statement user-defined function. (And since you should as a rule not use the latter two, I’ll use a stored procedure for my example). The optimizer treats the body of a stored procedure like an ad-hoc batch: when the procedure is invoked the plan cache is first checked, and when no cached plan for the procedure is found it is generated and then stored for future reuse. The key difference is how parameters are treated. To see this in action, run the below script in the AdventureWorks2012 sample database (though it probably also works in other versions of AdventureWorks), with the option to show the actual execution plan enabled. It contains four batches, to create a sample stored procedure, invoke it twice, and then drop the procedure again. The discussion below will focus on the second and third batches, with the two EXEC statements.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">CREATE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">PROC</font></span> dbo<span style="color:;"><font color="#808080">.</font></span>ParameterSniffingDemo</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font style="font-size:9.5pt;">@ProductID </font><span style="color:;"><font style="font-size:9.5pt;" color="#0000ff">int</font></span></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">AS</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span><span style="color:;"><font color="#ff00ff">SUM</font></span><span style="color:;"><font color="#808080">(</font></span>OrderQty</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">)</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>Sales<span style="color:;"><font color="#808080">.</font></span>SalesOrderDetail</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">WHERE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp; </span>ProductID <span style="color:;"><font color="#808080">=</font></span> @ProductID</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#008000">-- Run the procedure, then check the execution plan.</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> dbo<span style="color:;"><font color="#808080">.</font></span>ParameterSniffingDemo<span style="color:;"><font color="#0000ff"> </font></span>@ProductID <span style="color:;"><font color="#808080">=</font></span> 898</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#008000">-- Run the procedure again, for a different product.</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> dbo<span style="color:;"><font color="#808080">.</font></span>ParameterSniffingDemo<span style="color:;"><font color="#0000ff"> </font></span>@ProductID <span style="color:;"><font color="#808080">=</font></span> 897</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#008000">-- Clean up</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">DROP</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">PROC</font></span> dbo<span style="color:;"><font color="#808080">.</font></span>ParameterSniffingDemo</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The second batch in the query above, like any other batch, is first parsed and compiled. It is important to be aware that <b style="mso-bidi-font-weight:normal;">only the batch itself</b> is compiled at this time. Once the compilation is done, SQL Server executes the EXEC statement: it sets the parameter value to 870 and then passes control to the stored procedure. Since the procedure was just created, there is no plan in cache yet, so at this time the compiler is once more invoked to generate an execution plan for the procedure. If you read this sequence of events carefully, you will realize that, unlike “normal” variables, the value of parameter @ProductID has been set <b style="mso-bidi-font-weight:normal;">before the compiler is invoked</b>. The optimizer can read this value to use the specific statistics for ProductID 870 instead of the generic statistics it would use for a normal variable, to create an execution plan that is optimal for this “sniffed” value.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The third batch invokes the stored procedure again, with a different value passed into it. The batch itself is different from the second batch, so this batch, too, will be first compiled and then executed. And again control will pass to the stored procedure when execution starts, after setting the parameter to its value. But now the compiler will see that there already is an execution plan available for the stored procedure in the plan cache, so instead of invoking the (relatively expensive) optimization process again, it will reuse the existing plan.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><a mce_href="http://sqlblog.com/blogs/hugo_kornelis/image_519E9763.png" href="http://sqlblog.com/blogs/hugo_kornelis/image_519E9763.png"><img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="image" src="http://sqlblog.com/blogs/hugo_kornelis/image_thumb_7B326296.png" width="609" border="0" height="155"></a></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The picture above shows the execution plan of the third batch (the second execution plan in the output, as the CREATE PROC and DROP PROC statements do not generate any actual execution plans). Evidence of the parameter sniffing process is present in the plan, but not directly visible in the graphical representation. To see the evidence, you will have to right-click the top left SELECT operator, and then click “Properties” from the context menu. This brings up the full list of properties, as shown below:</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><a mce_href="http://sqlblog.com/blogs/hugo_kornelis/image_010D0630.png" href="http://sqlblog.com/blogs/hugo_kornelis/image_010D0630.png"><img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="image" src="http://sqlblog.com/blogs/hugo_kornelis/image_thumb_58FA5710.png" width="296" border="0" height="592"></a></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The “Parameter List” section is collapsed by default; I have already expanded it in the screenshot above. This is where you can see exactly what happened: there is one parameter in this query; it had a value of 898 (“Parameter Compiled Value”) when the plan was compiled and stored in cache, and during this specific execution the value of the parameter was 897 (“Parameter Runtime Value”).</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:13.5pt;">Variable sniffing</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Above I explain the general process of SQL Server compiling batches and entire stored procedures fully before execution starts; (non-parameter) variables do not have a value at compile time so the optimizer can only use more generic statistics. I left out a more specific part: statement level recompiles.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">SQL Server may discard old execution plans and restart the compilation process for various reasons. These reasons fall generally in one of three categories: correctness (any change that might cause the existing plan to fail or to return incorrect data, like dropping an index that might be used in the plan, modifying a table, changing a constraint that might have enabled a plan simplification, etc); performance (any change that might enable SQL Server to find a much faster plan, like adding an index, rebuilding statistics, adding constraints, etc); or because you tell it to (by explicitly clearing the plan cache, or by using hints).</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Some of the reasons for recompilation can occur while a multi-statement batch or stored procedure executes. SQL Server detects that before the next statement starts, and then <b style="mso-bidi-font-weight:normal;">that statement only</b> will be recompiled. This leads to a rather unique situation: execution has started, so now the variables do have a value, which enables the optimizer to sniff that value just as it sniffs parameters. Except … well, it doesn’t. At least not always. In fact, there is only one very specific case where SQL Server will sniff the variables: when a statement-level recompile occurs due to an explicit hint.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Here is a very simple example, again using AdventureWorks2012 (and again, probably working in other versions of AdventureWorks as well):</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">DECLARE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> @Variable <span style="color:;"><font color="#0000ff">varchar</font></span><span style="color:;"><font color="#808080">(</font></span>20</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">);</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SET</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> @Variable <span style="color:;"><font color="#808080">=</font></span> <span style="color:;"><font color="#ff0000">'B'</font></span></font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>FirstName<span style="color:;"><font color="#808080">,</font></span> LastName<span style="color:;"><font color="#808080">,</font></span> Title</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>Person<span style="color:;"><font color="#808080">.</font></span>Person</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">WHERE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp; </span>LastName <span style="color:;"><font color="#808080">&lt;</font></span> @Variable</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">OPTION </font></font></span><font style="font-size:9.5pt;"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#808080">(</font></span><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff">RECOMPILE</font></span></font><span style="font-family:;color:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;" color="#808080">);</font></span></font><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>FirstName<span style="color:;"><font color="#808080">,</font></span> LastName<span style="color:;"><font color="#808080">,</font></span> Title</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>Person<span style="color:;"><font color="#808080">.</font></span>Person</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">WHERE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp; </span>LastName <span style="color:;"><font color="#808080">&lt;</font></span> @Variable</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-us;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">If you copy this query and, <b style="mso-bidi-font-weight:normal;">without first running it!</b>, request an estimated execution plan, you will see the plan the optimizer creates when first compiling the batch:</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><a mce_href="http://sqlblog.com/blogs/hugo_kornelis/image_5ED4FAA9.png" href="http://sqlblog.com/blogs/hugo_kornelis/image_5ED4FAA9.png"><img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="image" src="http://sqlblog.com/blogs/hugo_kornelis/image_thumb_56DD5847.png" width="380" border="0" height="426"></a></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">While the batch is being compiled, the optimizer does not know the value of @Variable so it has to use a broad assumption – in the case of this type of inequality filter that assumption is that 30% of the rows will match, so the plan for the queries is based on an estimate of almost 6000 rows. The RECOMPILE hint on the second query does not affect the initial compilation of the batch; both queries get the exact same plan.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">If you then actually execute the batch, with the option to include the actual execution plan enabled, you will see this:</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><a mce_href="http://sqlblog.com/blogs/hugo_kornelis/image_71A97E53.png" href="http://sqlblog.com/blogs/hugo_kornelis/image_71A97E53.png"><img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="image" src="http://sqlblog.com/blogs/hugo_kornelis/image_thumb_309AFEEF.png" width="558" border="0" height="423"></a></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The first plan has changed. The RECOMPILE hint forces SQL Server to recompile this query, and because this is a statement-level recompile, the SET statement has already executed. SQL Server can sniff the value ‘B’ in @Variable, use that to estimate that only about 900 rows will match, and then generate a plan that is optimized for that lower number of rows. You can play around with the value in @Variable to see that the plan used for the first query can actually change depending on this value.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The plan for the second query will never change. There is no RECOMPILE hint, and there were no other reasons for SQL Server to recompile this statement, so this query will always use the plan that was generated when the batch was compiled.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Fun fact: if you request an estimated execution plan <b style="mso-bidi-font-weight:normal;">after</b> running the query, you will get the last plan that was actually used. That is because the statement-level recompile will update the plan cache entry for this batch with the new execution plan. The requested estimated execution plan will be presented to you from this plan cache entry. When you actually run the batch again, the initial compilation of the batch will also use the cached entry without redoing the full compilation process, but at run-time the RECOMPILE hint will still trigger a recompilation of the first query only – which will now result in the same plan again, unless you modified the data in the Person.Person table. This is a very important consideration. A lot of people think that adding OPTION (RECOMPILE) to a query results in the execution plan not being cached; this is not true. Those queries still result in the same memory footprint on the plan cache, with the additional cost of not only compiling the query whenever it runs, but also updating the plan in the cache on every execution.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Another interesting observation can be made when you right-click the SELECT operators on the two plans above and look at the properties. The second plan, which was not recompiled and sniffed, does have a Parameter List section in the plan, but in this case there is only a Parameter Runtime Value, no Parameter Compiled Value:</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><a mce_href="http://sqlblog.com/blogs/hugo_kornelis/image_4F7172CD.png" href="http://sqlblog.com/blogs/hugo_kornelis/image_4F7172CD.png"><img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="image" src="http://sqlblog.com/blogs/hugo_kornelis/image_thumb_40C6C6E8.png" width="296" border="0" height="85"></a></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">(The term “parameter” is confusing; within the context of execution plan properties SQL Server uses this term for every variable that is used in the query, regardless of whether they are actual parameters, or “normal”, non-parameter variables).</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;"></font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">For the first plan, the properties of the SELECT operator do not include a Parameter List section at all, which is even more confusing – this was the section where we saw evidence of parameter sniffing, and now that a variable is sniffed there is no evidence at all! And how can SQL Server even produce the correct results without embedding the variable and its runtime value in the plan? To get an answer to that question, we’ll have to look at the properties of another operator, the Index Seek (NonClustered) at the far right. And in this case we do not even have to open the full property list, we can just hover our mouse over the operator and wait for the tooltip window to pop up:</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><a mce_href="http://sqlblog.com/blogs/hugo_kornelis/image_523727C0.png" href="http://sqlblog.com/blogs/hugo_kornelis/image_523727C0.png"><img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="image" src="http://sqlblog.com/blogs/hugo_kornelis/image_thumb_3F822E09.png" width="290" border="0" height="55"></a></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"></span><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">This shows that the plan that is used for the statement with the OPTION (RECOMPILE) hint does not reference @Variable at all. What actually happened is that, during the statement level recompile, the <b style="mso-bidi-font-weight:normal;">parser</b> inspected the current value of @Variable and then replaced all references to this variable in the query (or rather, in the internal representation of the query) by the value. The input that was finally received by the optimizer was exactly the same as if we had submitted the query below:</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>FirstName<span style="color:;"><font color="#808080">,</font></span> LastName<span style="color:;"><font color="#808080">,</font></span> Title</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>Person<span style="color:;"><font color="#808080">.</font></span>Person</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">WHERE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp; </span>LastName <span style="color:;"><font color="#808080">&lt;</font></span> </font><span style="color:;"><font style="font-size:9.5pt;" color="#ff0000">N'B'</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">OPTION </font></font></span><font style="font-size:9.5pt;"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#808080">(</font></span><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff">RECOMPILE</font></span></font><span style="font-family:;color:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;" color="#808080">);</font></span></font><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-us;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">For “normal” parameter sniffing, this would not be a safe implementation. The next call to the stored procedure could pass a different parameter value, and if the sniffed value were hardcoded in the plan, then the results would obviously be incorrect. That’s why a plan with parameter sniffing must keep the parameter; it optimizes for the sniffed value, but will also produce correct results for other values. In the case of variable sniffing, there is no need to keep the variable as a variable in the execution plan. A cached plan will only be reused if there is a full textual match on the full query text, which includes the OPTION (RECOMPILE) hint – and that option guarantees that the cached plan will be overwritten with a new plan rather than be reused. So the choice to implement variable sniffing differently, by directly injecting the values into the plan, is safe.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">But that same safe choice also results in a loss of variable sniffing in other scenarios. When a statement-level recompile occurs for a different reason, for instance because enough rows were added to a table to trigger an automatic update of the statistics on that table, then no sniffing is done. This makes sense when you consider what would otherwise happen. Suppose I have a batch and the third statement uses a variable; just before it executes the threshold for automatic statistics update is hit so new statistics pop up and the optimizer recompiles the query. If it would sniff the variable, it would hard-code the sniffed value in the plan, then replace the old cached plan with the new plan. Next time I execute the same batch, the variable can have a new value – but the text of the batch has not changed, and it is unlikely that there will be a statement-level recompile for another reason. So the updated plan from the cache, that now includes a hard-coded value, would be used – but that value is no longer correct and wrong results would be returned. That is of course not acceptable, and for that reason SQL Server will only sniff variables when a statement-level recompile is forced by the OPTION (RECOMPILE) query hint.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">In theory, it would have been possible for Microsoft to implement a second form of variable sniffing, using the same method as for parameter sniffing. In reality, that is not the choice Microsoft made. In order to ensure that a statement-level recompile that is not caused by OPTION (RECOMPILE) produces a “safe” plan, the variables are simply not sniffed. The new plan will be based on the new statistics, but it will still use the generic estimates.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:13.5pt;">Cardinality sniffing</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">Table variables behave in many ways exactly the same as normal variables. This includes the optimization process. So when a batch or stored procedure is submitted, the parser interprets the declaration of the table variable and then compilation starts without any data being in the table variable. Based on actual reality at the time of compilation, one might expect an estimate of zero rows. However, the optimizer always assumes at least one row (unless the query includes a filter that cannot possibly be true). If you run the query below, you will see that the first two SELECT queries both have an estimated rowcount of 1, even though the actual rowcount is 0 for the first query and 19972 for the second.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">DECLARE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> @TabVar </font><span style="color:;"><font style="font-size:9.5pt;" color="#0000ff">table</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><span style="mso-spacerun:yes;"><font color="#0000ff"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></font></span></span><font style="font-size:9.5pt;"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#808080">(</font></span></font><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;">PersonID <span style="color:;"><font color="#0000ff">int</font></span> <span style="color:;"><font color="#808080">NOT</font></span> <span style="color:;"><font color="#808080">NULL</font></span> <span style="color:;"><font color="#0000ff">PRIMARY</font></span> <span style="color:;"><font color="#0000ff">KEY</font></span></font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">);</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>PersonID</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>@TabVar</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">INSERT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>@TabVar</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>BusinessEntityID</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>Person<span style="color:;"><font color="#808080">.</font></span>Person</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>PersonID</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>@TabVar</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>PersonID</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>@TabVar</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">OPTION </font></font></span><font style="font-size:9.5pt;"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#808080">(</font></span><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff">RECOMPILE</font></span></font><span style="font-family:;color:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;" color="#808080">);</font></span></font><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">In the case of the simple queries above, this huge mistake in cardinality estimation does not affect the execution plan. But in more complex queries this can often result in very slow running queries. This is one of many reasons why most people tend to prefer temporary tables over table variables unless they know for sure that there will never be more than a handful of rows involved. This problem can be avoided by adding OPTION (RECOMPILE), as shown in the last SELECT above. This forces a statement-level recompile and now the actual number of rows in @TabVar can be used by the optimizer. This can often help prevent execution plans with terrible performance, but at the price of a full compilation for the statement every time it executes.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">All of the above is pretty well known and described at many places; I only include this basic information because it is important to understand what “cardinality sniffing” is. Cardinality sniffing is related to parameter sniffing, because it only relates to parameters passed into stored procedures (and other executable code modules). It is also related to table variables. In fact, cardinality sniffing is specifically related to table-valued parameters – table variables passed as a parameter into a stored procedure. Here is an example:</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#008000">-- Define a type for the table variables</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">CREATE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">TYPE</font></span> TabType <span style="color:;"><font color="#0000ff">AS</font></span> </font><span style="color:;"><font style="font-size:9.5pt;" color="#0000ff">TABLE</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><span style="mso-spacerun:yes;"><font color="#0000ff"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></font></span></span><font style="font-size:9.5pt;"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#808080">(</font></span></font><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;">PersonID <span style="color:;"><font color="#0000ff">int</font></span> <span style="color:;"><font color="#808080">NOT</font></span> <span style="color:;"><font color="#808080">NULL</font></span> <span style="color:;"><font color="#0000ff">PRIMARY</font></span> <span style="color:;"><font color="#0000ff">KEY</font></span></font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">);</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#008000">-- Create a stored procedure that uses the table variable</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">CREATE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">PROC</font></span> dbo<span style="color:;"><font color="#808080">.</font></span>SniffCardinality</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font style="font-size:9.5pt;">@InputTable TabType </font><span style="color:;"><font style="font-size:9.5pt;" color="#0000ff">READONLY</font></span></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">AS</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>PersonID</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>@InputTable</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#008000">-- Create and populate a table variable</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">DECLARE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> @TabVar <span style="color:;"><font color="#0000ff">AS</font></span> TabType</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">INSERT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>@TabVar</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>BusinessEntityID</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp;&nbsp; </span>Person<span style="color:;"><font color="#808080">.</font></span>Person</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#008000">-- Invoke the stored procedure the first time</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> dbo<span style="color:;"><font color="#808080">.</font></span>SniffCardinality<span style="color:;"><font color="#0000ff"> </font></span>@TabVar</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#008000">-- Now remove some of the rows from the table variable</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">DELETE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp; </span>@TabVar</font></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">WHERE</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"><span style="mso-spacerun:yes;">&nbsp;&nbsp; </span>PersonID <span style="color:;"><font color="#808080">&lt;</font></span> 20000</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#008000">-- Invoke the stored procedure again</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> dbo<span style="color:;"><font color="#808080">.</font></span>SniffCardinality<span style="color:;"><font color="#0000ff"> </font></span>@TabVar</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#008000">-- Clean up</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">DROP</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">PROC</font></span> dbo<span style="color:;"><font color="#808080">.</font></span>SniffCardinality</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><font face="Consolas"><span style="font-family:;color:;mso-ansi-language:en-us;"><font color="#0000ff"><font style="font-size:9.5pt;">DROP</font></font></span><span style="font-family:;mso-ansi-language:en-us;"><font style="font-size:9.5pt;"> <span style="color:;"><font color="#0000ff">TYPE</font></span> TabType</font><span style="color:;"><font style="font-size:9.5pt;" color="#808080">;</font></span></span></font></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;text-autospace:;margin-right:0cm;mso-layout-grid-align:none;" align="left"><span style="font-family:;color:;mso-ansi-language:en-us;"><font face="Consolas"><font style="font-size:9.5pt;" color="#0000ff">GO</font></font></span><span style="font-family:;mso-ansi-language:en-us;"></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">If you run the batch above with the option to include the actual execution plan enabled, you will see a bunch of plans for all the queries in the last batch. The second and fourth are the executions of the stored procedure. Previously when we ran the same SELECT statement in a batch, the estimated number of rows for the table variable was 1. Now the estimates are different, as shown in the picture below (note that I edited the picture to remove irrelevant execution plans and include two tooltip windows): </font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><a mce_href="http://sqlblog.com/blogs/hugo_kornelis/image_50F28EE1.png" href="http://sqlblog.com/blogs/hugo_kornelis/image_50F28EE1.png"><img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="image" src="http://sqlblog.com/blogs/hugo_kornelis/image_thumb_24D591F0.png" width="403" border="0" height="438"></a></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"></span><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">As you see, the first estimate is exactly correct. That is because the table-valued parameter is used by the optimizer just as it uses other parameters. So when the stored procedure is first executed and no plan for it is in cache yet, it will sniff the table-valued parameter just as it sniffs other parameters. Now it is important to realize that this sniffing is limited. The optimizer will not read data from the table variable to get insight on the data in it. It only sniffs the metadata that is available at the time of compiling the plan. And because table variables do not have statistics, that metadata is limited to only the number of rows in the table variable that is passed into the stored procedure for the first execution.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">The second estimate is wrong. After the first call to the stored procedure we deleted most of the rows from the table variable, but the execution plans that are used for the stored procedure are all still optimized on the original row count. That is because the execution simply reused the previously compiled plan from the plan cache. A change in the cardinality on the table-valued parameter, like a change to the value of a regular parameter, is no reason to recompile the execution plan for the stored procedure.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">I already mentioned that cardinality sniffing has, to the best of my knowledge, never been documented before. That is not really surprising. I have yet to see my first table-valued parameter in “real” client code, and I hear almost nobody ever talk about them, so the feature appears to be pretty niche. However, when you happen to work on a system that does use table-valued parameters, then you might be faced with cardinality sniffing and its possible performance consequences. (And if not, then you can at least add “Hey, would you like to sniff my cardinality?” to your collection of useless pickup lines).</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><b><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:13.5pt;">Conclusion</font></font></span></b></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">In this post, I first elaborated a bit on the relatively well-known concept of parameter sniffing, giving some background information into the internals at play in this process. I then went on to explain the much lesser known concept of variable sniffing, and proved that (unlike popular opinion by those who do talk or write about this concept) it actually uses quite different internal mechanisms from parameter sniffing, and that for this reason variable sniffing only happens when a recompile is manually enforced.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">In the last paragraph I then introduces a previously unknown form of sniffing: cardinality sniffing. In a process similar to parameter sniffing, the number of rows in a table variable can be sniffed when it is passed as a table-valued parameter into a stored procedure.</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">&nbsp;</font></font></span></p> <p class="MsoNormal" style="list-style-type:disc;margin-left:0cm;margin-top:0cm;margin-right:0cm;" align="left"><span style="mso-ansi-language:en-gb;"><font face="Times New Roman"><font style="font-size:12pt;">In the opening paragraph I already hinted that parameter sniffing, though well-known, is also very misunderstood. It is neither “bad” (as suggested by many experts), nor “mostly good with an occasional exception” (as suggested by most others), but actually “sometimes good, sometimes bad, and mostly irrelevant”. I will explain this in my next blog post on this subject.</font></font></span></p>Query Store - Forced Doesn’t Always Mean Forcedhttp://sqlblog.com/blogs/andrew_kelly/archive/2016/09/18/query-store-forced-doesn-t-always-mean-forced.aspxMon, 19 Sep 2016 02:30:00 GMT21093a07-8b3d-42db-8cbf-3350fcbf5496:61869Andrew Kelly<p>&nbsp;</p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;text-indent:0.5in;"><font face="Calibri"><font style="font-size:11pt;">The new </font></font><font style="font-size:11pt;"><a href="https://msdn.microsoft.com/en-US/library/dn817826.aspx" target="_blank" mce_href="https://msdn.microsoft.com/en-US/library/dn817826.aspx">Query Store</a><font color="#0563c1" face="Calibri"></font><font face="Calibri"> feature in SQL Server 2016 is a great new addition that we have been anticipating for many years now. There are already a bunch of articles out there that explain what it is even how to go about using it so I won’t repeat that here. However there is one aspect of the feature that has been poorly documented and even a little bit misleading that I want to go over. Please note that as I was writing this blog some of the documentation has been updated by MS and I want to thank them for doing so. The part of this new feature that I want to discuss is the forcing of query plans. After all the ability to force a particular query plan is certainly one of the main reasons this feature exists.<span style="mso-spacerun:yes;">&nbsp; </span>As you read along keep in mind the Query Store tracks at the query or statement level not the overall batch or procedure. Within a particular Query Store (which is database specific) it assigns a unique query_id for each unique statement as defined by the </font><a href="https://technet.microsoft.com/en-us/library/cc645887(v=sql.105).aspx" target="_blank" mce_href="https://technet.microsoft.com/en-us/library/cc645887(v=sql.105).aspx">query_hash</a><font color="#0563c1" face="Calibri"></font><font face="Calibri">. We will also have a unique plan_id which is based on the </font><a href="https://technet.microsoft.com/en-us/library/cc645887(v=sql.105).aspx" target="_blank" mce_href="https://technet.microsoft.com/en-us/library/cc645887(v=sql.105).aspx">query_plan_hash</a><font color="#0563c1" face="Calibri"></font></font><font face="Calibri"><font style="font-size:11pt;"> for a given query_Id. If the query plan for a given query_id changes over time we will get another entry in the Query Store for that combination of the query_id and the new plan_id. This allows us to see the history for a given query for each unique query plan used for such query. The run time statistics such as reads, writes, duration etc. are tied to each combination of the query_id and plan_id. It actually gets a bit more complex in that there are time intervals that come into play as well but for simplicity sake let’s ignore them here, especially since all stats are still tied to the query_id and plan_id combination when aggregated. What this does is allow us to track and see how each plan performed for that query and is very useful information. </font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;text-indent:0.5in;"><font face="Calibri"><font style="font-size:11pt;">This is after all what allows us to be able to decide which plan we want the query to use. Let’s say we had a situation in which over time we ended up with 2 different <font face="Calibri"><font style="font-size:11pt;">query plans due to recompilation and parameter sniffing. Each plan may have been perfect for the parameters passed in on the first execution after each recompile and if </font></font><font face="Calibri"><font style="font-size:11pt;">called with that same parameter each time things are great. However let’s also assume the 2nd time we got a plan it was based on a value passed into the procedure that was </font></font><font face="Calibri"><font style="font-size:11pt;"></font></font></font></font><font face="Calibri"><font style="font-size:11pt;"></font></font><font face="Calibri"><font style="font-size:11pt;">not typical for most executions of this procedure. In fact only .1% of the time will this be a valid plan and thus gives us very bad performance for 99.9% of the subsequent calls to this procedure with other values for parameter passed in. That means most of the time the performance will not be what we want and may cause lots of performance issues.<span style="mso-spacerun:yes;">&nbsp; </span>We can try to recompile the procedure and hope we get the right values passed in to give us the plan that is best for 99.9% of the time but that is somewhat of a gamble. Instead we can use this great new feature called the Query Store and we can force the previous plan that gave us the great performance the majority of the time. We could see from the history of each plan which plan worked best by looking at the statistics kept for each plan.<span style="mso-spacerun:yes;">&nbsp; </span>This would be true even if there were a dozen plans. SSMS even has graphical tools to help us with that decision making and also allows us to force that plan for subsequent runs. We can do this via TSQL as well of course. </font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;text-indent:0.5in;"><font face="Calibri"><font style="font-size:11pt;">Let’s summarize the situation. We have 2 query plans in the Query Store and the most recent one is also the current plan in the plan cache that is being used for all new executions of this procedure. But that plan is bad for all but .1% of the values we may pass in to the procedure. The previous plan in the Query Store is a much better plan overall and that is the one we want to ensure is used regardless of the value passed in. As such we go ahead and force the plan using the provided tools or TSQL which sets the is_forced_plan to 1 for the 1st plan in sys.query_store_plan. As a simplified explanation this action invokes a recompile and the current plan (which was bad) is replaced with a new plan that is based on the one we forced. That new plan now becomes the current one in the cache and is now the one in the Query Store that all new statistics are tied to as well.</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;text-indent:0.5in;"><font face="Calibri"><font style="font-size:11pt;">Most people would think that if they forced a particular plan that was in the Query Store and it was marked as forced we would in fact be using that very same plan identified by the plan_id and query_plan_hash which is tied to the plan we forced. Keep in mind that if there were problems with the recompile such as it was missing an index that was there when the original plan was created we would get an error which would be listed in the force failure columns and a different plan would obviously need to be used. Errors aside most of the time when we force a plan it gets recompiled and we end up with the same plan as that which we forced. If that plan is the same as the original one we forced it will have the same query_plan_hash and thus the same plan_id.<span style="mso-spacerun:yes;">&nbsp; </span>All future executions will now use that plan and all statistics will be tied to it as well.<span style="mso-spacerun:yes;">&nbsp; </span>This is exactly what we would expect once we forced a plan in the Query Store.</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;text-indent:0.5in;"><font face="Calibri"><font style="font-size:11pt;">OK so here is where things may not happen exactly as you would expect. When you force a plan as stated earlier it goes thru a recompilation process and it tries to generate the same or very similar plan as the one you picked. Again assuming nothing has changed such as objects being created or dropped most people would assume it would give us the exact plan we forced. However it is not guaranteed that you will get the same exact plan and in fact it may have a different plan_id and query_plan_hash altogether. How can it do that you say, after all didn’t I FORCE that plan? Yes you did but during the recompile process it may have found a slightly different (maybe better maybe not) way to accomplish the same task that is very similar yet somewhat different than the original plan. For instance the original plan was a Clustered Index scan as is the new one, but the new one may have added, moved or removed an operator which still gives it a valid plan just not the exact one you forced. In this case since it gets a new plan_id all subsequent statistics will be tied to the new plan_id and not the one you actually forced. The is_forced_plan is still set to 1 for the original plan that you forced where as the one currently being used is set to 0.<span style="mso-spacerun:yes;">&nbsp; </span>That part can be a bit confusing to some people unless they understand how this came to be. </font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;text-indent:0.5in;"><font face="Calibri"><font style="font-size:11pt;">I realize this has been a very long winded explanation but in my opinion necessary to ensure everyone fully understands this potential anomaly so that when or if they see it they will know it is by design and not a bug. It is important to keep in mind that the new plan even if different will be similar to the original plan (the one you forced). As such it will likely perform just fine and get the intended job done which was to get the procedure using a plan that was more appropriate for the majority of the calls. The differences in the plan from the actual forced plan may or may not be noticeable from an overall performance standpoint and as always it depends. But if you are tracking the statistics in the Query Store it is important to know that even if there are no warnings of a failed forced plan the currently active plan may have a different plan_id than the one you manually forced.<span style="mso-spacerun:yes;">&nbsp; </span>One other thing to note is that if the current query plan is recompiled it will always go back to the plan that is marked as forced and that will be the one used in the recompile process. So it may very well pick the original plan again and now you are back to operating as you expected to begin with. </font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;text-indent:0.5in;"><font face="Calibri"><font style="font-size:11pt;">Don’t in any way take this post to be a warning not to use the Query Store because it is not. This is simply an attempt to make people aware of the potential behavior that is not well documented or can be confusing to many of us. I too was confused until I dug deep enough to figure out what was going on and hopefully this will save you the time and effort to do the same.<span style="mso-spacerun:yes;">&nbsp; </span>Here is an example of how you can see this behavior and why it happens. I think it will go a long way towards making people aware of this behavior and understanding why it is normal albeit a bit unexpected.</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;text-indent:0.5in;"><font face="Calibri"><span style="mso-spacerun:yes;"><font style="font-size:11pt;">&nbsp;</font></span><font style="font-size:11pt;">This example uses the new <a href="https://blogs.technet.microsoft.com/dataplatforminsider/2016/06/09/wideworldimporters-the-new-sql-server-sample-database/" target="_blank" mce_href="https://blogs.technet.microsoft.com/dataplatforminsider/2016/06/09/wideworldimporters-the-new-sql-server-sample-database/">WideWorldImporters</a></font></font><font style="font-size:11pt;"><font color="#0563c1" face="Calibri"></font></font><font face="Calibri"><font style="font-size:11pt;"> sample database for SQL Server 2016 with just a few slight modifications. First I update a single row in the Sales.Invoices table to set the DeliveryMedthodID = 1. All other rows have a DeliveryMethodID = 3. I then create a stored procedure as shown below which queries the Invoices table using the DeliveryMethodID tied to the input parameter of the procedure.</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;text-indent:0.5in;"><font face="Calibri"><font style="font-size:11pt;">&nbsp;</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">USE</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> WideWorldImporters </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#008000" style="font-size:9.5pt;">-- This allows for a NCI Seek since thre is only 1 row with this value</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff00ff"><font style="font-size:9.5pt;">UPDATE</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> Sales</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">Invoices </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">SET</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> DeliveryMethodID </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> 1 </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">WHERE</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> InvoiceID </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> 425 </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">IF</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff00ff">OBJECT_ID</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">(</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff0000">'Sales.GetInvoicesByDeliveryMethodID'</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff0000">N'P'</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">)</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">IS</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">NOT</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">NULL</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp; </font></span></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">DROP</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">PROCEDURE</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> Sales</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;">GetInvoicesByDeliveryMethodID</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">CREATE</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">PROCEDURE</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> Sales</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;">GetInvoicesByDeliveryMethodID</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;">@DeliveryMethodID </font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">INT</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;"> </font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">AS</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">BEGIN</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp; </font></span></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">SET</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">NOCOUNT</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">ON</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp; </font></span></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">SELECT</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">TOP </font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">(</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">10000</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">)</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">*</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">FROM</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> [WideWorldImporters]</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">[Sales]</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">[Invoices] </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">AS</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;"> i</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">WHERE</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> i</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">DeliveryMethodID </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> @DeliveryMethodID </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">END</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">&nbsp;</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">I then clear out the query store tables using this command:</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">ALTER</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">DATABASE</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> [WideWorldImporters] </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">SET</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">QUERY_STORE</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">CLEAR</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">&nbsp;</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">Throughout the demo you can use this query to see the results in the Query Store stables.</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">SELECT</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#008000" style="font-size:9.5pt;">--CAST(p.query_plan AS XML) AS [XML Plan],</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font style="font-size:9.5pt;">q</font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_id</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> q</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_hash</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> p</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">plan_id</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> p</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;">query_plan_hash</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> p</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">is_forced_plan</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> last_force_failure_reason_desc </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">AS</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;"> [Failures]</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff00ff">SUM</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">(</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">s</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">count_executions</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">)</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">AS</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> [Execs]</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff00ff">SUM</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">(</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">s</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">avg_logical_io_reads</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">)</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">AS</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;"> [Avg LReads]</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font style="font-size:9.5pt;">&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff00ff">MAX</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">(</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">s</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">last_execution_time</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">)</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">AS</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> [Last Execution]</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff00ff">MAX</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">(</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">q</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">last_compile_start_time</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">)</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">AS</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> [Last Compile]</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> t</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;">query_sql_text</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">FROM</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#00ff00">sys</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_store_query </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">AS</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;"> q</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080"><font style="font-size:9.5pt;">JOIN</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#00ff00">sys</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_store_query_text </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">AS</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> t </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">ON</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> q</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_text_id </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> t</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;">query_text_id</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080"><font style="font-size:9.5pt;">JOIN</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#00ff00">sys</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_store_plan </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">AS</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> p </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">ON</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> q</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_id </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> p</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;">query_id</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080"><font style="font-size:9.5pt;">JOIN</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#00ff00">sys</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_store_runtime_stats </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">AS</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> s </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">ON</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> p</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">plan_id </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> s</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;">plan_id</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">WHERE</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> t</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_sql_text </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">LIKE</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff0000">'%(@DeliveryMethodID int)SELECT%'</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">AND</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> t</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_sql_text </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">NOT</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">LIKE</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff0000">'SELECT%'</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;"> </font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">GROUP</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">BY</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> q</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_id</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> q</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_hash</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> p</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">plan_id</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> p</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">query_plan_hash</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> p</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">is_forced_plan</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> last_force_failure_reason_desc</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> t</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font style="font-size:9.5pt;">query_sql_text</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">ORDER</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff">BY</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;"> q</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;">query_id</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;"> p</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;">plan_id </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;line-height:10pt;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">I then will execute a series of commands as shown directly below which will show the behavior outlined in the blog above. Just below this code is a step by step description of what happens and why, including the query plans that result from each stage. </font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> Sales</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">GetInvoicesByDeliveryMethodID</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"> </font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">@DeliveryMethodID </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> 3 </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> Sales</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">GetInvoicesByDeliveryMethodID</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"> </font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">@DeliveryMethodID </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> 1 </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#800000">sp_recompile</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"> </font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#ff0000">N'Sales.GetInvoicesByDeliveryMethodID'</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><span style="mso-spacerun:yes;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> Sales</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">GetInvoicesByDeliveryMethodID</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"> </font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">@DeliveryMethodID </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> 1 </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> Sales</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">GetInvoicesByDeliveryMethodID</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"> </font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">@DeliveryMethodID </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> 3 </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#008000" style="font-size:9.5pt;">-- Force the scan plan<span style="mso-spacerun:yes;">&nbsp; </span>(query_id, Plan_id)</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#00ff00">sys</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">sp_query_store_force_plan</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"> </font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">1</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">,</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">1</span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font style="font-size:9.5pt;">&nbsp;</font></font></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><font face="Consolas"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"><font style="font-size:9.5pt;">EXEC</font></font></span><font style="font-size:9.5pt;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> Sales</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">.</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">GetInvoicesByDeliveryMethodID</span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#0000ff"> </font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;">@DeliveryMethodID </span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080">=</font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"> 1 </span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font color="#808080" style="font-size:9.5pt;">;</font></span></font><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:0pt;line-height:normal;text-autospace:;mso-layout-grid-align:none;"><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"><font face="Consolas"><font color="#0000ff" style="font-size:9.5pt;">GO</font></font></span><span style="font-family:;background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;color:;mso-bidi-font-family:consolas;mso-highlight:white;"></span></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">&nbsp;</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">First we execute the stored procedure twice ensuring we pass in the value = 3 for the first execution. Since all but 1 row in the table will math that value we will get a plan that is a full scan of the Clustered Index on the Invoices table as shown below, which includes a filter operator after the scan to filter the WHERE clause SARG. When you run the supplied query you will see that we have 2 executions for the same combination of query_id and plan_id in the Query Store tables.</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><a href="http://sqlblog.com/blogs/andrew_kelly/Plan1_426EB239.jpg" mce_href="http://sqlblog.com/blogs/andrew_kelly/Plan1_426EB239.jpg"><img width="743" height="91" title="Plan1" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="Plan1" src="http://sqlblog.com/blogs/andrew_kelly/Plan1_thumb_68D09584.jpg" border="0"></a></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">Next we recompile the stored procedure to simulate a situation in which the current plan becomes invalid such as statistics being updated on the underlying table or index. </font><span style="mso-spacerun:yes;"><font style="font-size:11pt;">&nbsp;</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">Then we execute the procedure two more times careful to pass in the value = 1 for the parameter the first time after the recompile. This simulates a situation in which we now have a query plan that was based on an atypical parameter and as mentioned in the blog above will give us poor performance for any future executions with a value other than 1.<span style="mso-spacerun:yes;">&nbsp; </span>The reason is that the new plan was based on a single row being returned vs. 10K rows and was able to utilize the nonclustered index on the DeliveryMethodID as shown below.</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;"></font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;"><a href="http://sqlblog.com/blogs/andrew_kelly/Plan2_59308A73.jpg" mce_href="http://sqlblog.com/blogs/andrew_kelly/Plan2_59308A73.jpg"><img width="751" height="160" title="Plan2" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="Plan2" src="http://sqlblog.com/blogs/andrew_kelly/Plan2_thumb_4D9ACD34.jpg" border="0"></a></font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">While the index seek may be great for a single row it is far more expensive than a scan when retrieving 10K rows. This can be seen by looking at the Avg LReads column which shows the new plan over twice the reads as the original plan. </font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">Once we realize this we quickly decide to force the original query plan by using the system supplied stored procedure. Please note that the two parameters used in the example for the forcing may not match the ones in your environment.<span style="mso-spacerun:yes;">&nbsp; </span>If not please change them accordingly. The first parameter is for the query_id and the 2<sup>nd</sup> is for the plan_id that you wish future executions use. </font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">Finally we then execute the procedure once more using the parameter value = 1 and then take another look at the Query Store results.<span style="mso-spacerun:yes;">&nbsp; </span>We now see that there is a 3<sup>rd</sup> plan that was generated for that query_id and it has a different plan_id and query_plan_hash than the one we forced. <span style="mso-spacerun:yes;">&nbsp;</span>We see that the is_forced_plan column is set for the one we forced and not the new one that was generated as a result. However you can see that the statistics for any new executions are tied to the newly generated plan and not the one marked as forced. Again this does not mean it is broken or that there is a bug it is simply a different implementation then most people would have expected when first using the Query Store and especially if they read the documentation as it existed before a few days ago.</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">I can see that you have one last question though and that is “why did it generate a new plan when it should have used the original one since the original plan is still valid”? That is a good question and luckily I have a good answer</font></font><font style="font-size:11pt;"><span style="font-family:;mso-ascii-font-family:calibri;mso-hansi-font-family:calibri;mso-char-type:symbol;mso-symbol-font-family:wingdings;mso-ascii-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;"><span style="mso-char-type:symbol;mso-symbol-font-family:wingdings;"><font face="Wingdings">J</font></span></span></font><font face="Calibri"><font style="font-size:11pt;">. If we look at the plan that was generated below we will see a slight difference in the overall plan. Notice that we no longer have the filter operator highlighted in the 1st plan. Instead if we look at the properties for the scan operator we see that the optimize chose to push the predicate (WHERE DeliveryMethodID = @DeliveryMethodID) as part of the scan operation itself. If you remember the original plan sniffed the parameter passed in on the first execution and it was a 3 which matched all rows but one. The optimizer knew that all rows but 1 matched this value and we had a TOP 10K on a table with much more rows than that. So it made sense that it could simply push ~10K rows down and filter later. However when we forced the plan which caused a recompile the very next time we executed the procedure we passed in a 1 which only has 1 matching row. Normally that would use the nonclustered index and do a seek. But since the original plan that we forced was a clustered index scan this needed to also do a nonclustered index scan. But this time the optimizer saw that the value we were looking for only matched one row and decided that it could filter on that row during the scan better than filtering later in the process. Or it simply found this plan was close enough to the original and stopped there. I honestly don’t know which but suspect the 1st explanation is more correct.</font><span style="mso-spacerun:yes;"><font style="font-size:11pt;">&nbsp;</font></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><span style="mso-spacerun:yes;"><a href="http://sqlblog.com/blogs/andrew_kelly/Plan3_7B1BECF7.jpg" mce_href="http://sqlblog.com/blogs/andrew_kelly/Plan3_7B1BECF7.jpg"><img width="788" height="363" title="Plan3" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" alt="Plan3" src="http://sqlblog.com/blogs/andrew_kelly/Plan3_thumb_6F862FB8.jpg" border="0"></a></span></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">In either case the point is that we can indeed end up with different plans than what we have explicitly forced using the Query Store. Most of the time this will likely never be a problem but there are always exceptions and you may find some day the plan it generated is not what you ideally want and this is why. Also be aware that a recompile can happened for many reasons at any time so exactly which plan it will use going forward may change over time. Chances are whichever plan it choses will still be better than the one that caused you to force one in the first place if you did your homework correctly.<span style="mso-spacerun:yes;">&nbsp; </span>Another question I hear is “why not just use a query hint such as OPTIMIZE FOR in the procedure and be done with it”? Well one good reason is that you may be using 3<sup>rd</sup> party software that uses procedures in which you are not allowed to change. This in my opinion is a much better and easier solution than using plan guides.<span style="mso-spacerun:yes;">&nbsp; </span>And one last tip is that once you do force a plan you should check it regularly to ensure it is still doing what you expect. Your fellow DBA may decide to make changes to the objects this plan references and make your forced plan invalid without you knowing. The Query store is just another tool in our SQL Server toolbox that certainly has the potential to give us great benefit but if misused or neglected can have the opposite effect. </font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">If you are going to the </font></font><font style="font-size:11pt;"><a><font color="#0563c1" face="Calibri">PASS Summit 2016</font></a><font face="Calibri"> and Query Store sounds interesting to you and you want to know more please attend my </font><a><font color="#0563c1" face="Calibri">session</font></a></font><font face="Calibri"><font style="font-size:11pt;"> for a better overall summary of what it is and how to use it.</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">If you made it this far thanks for hanging in there and good luck,</font></font></p> <p align="left" class="MsoNormal" style="list-style-type:disc;margin-bottom:8pt;line-height:12pt;"><font face="Calibri"><font style="font-size:11pt;">Andy</font></font></p>