{"id":92867,"date":"2021-11-29T17:00:45","date_gmt":"2021-11-29T17:00:45","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=92867"},"modified":"2022-05-06T00:13:33","modified_gmt":"2022-05-06T00:13:33","slug":"query-store-hints-powerful","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/query-store-hints-powerful\/","title":{"rendered":"Query Store and hints: More Powerful than ever"},"content":{"rendered":"<p>I need to confess: I&#8217;m proud of the article <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/database-administration-sql-server\/query-store-parameterization-problems\/\">Query Store and Parameterization Problems<\/a>\u00a0I wrote. Today it&#8217;s no news at all (although some people may not know the details about plan guides I included in the article) but I wrote it in 2017, based on <strong>SQL Server 2016<\/strong>, when the idea of identifying parameter sniffing with query store was very fresh.<\/p>\n<p>Jump to today: <strong>Query Store<\/strong> got a new feature, <strong>Query Store Hints<\/strong>. This feature is already being the base for many performance improvements in <strong>SQL Server<\/strong>. The idea is the possibility to include query hints on the query store queries.<\/p>\n<p>In my article about parameterization, I made use of plan guides exactly because it was the only way to include hints on the queries. <strong>Query Store Hints<\/strong> change that, and in my opinion, they make plan guides obsolete. What other reason would make you still use a plan guide today? I would love to hear about it on the comments.<\/p>\n<h2>\nPreparing the Environment<\/h2>\n<p>Let&#8217;s prepare an environment for some tests.<\/p>\n<h3>First Step: Provision a demonstration database<\/h3>\n<p>When you are provisioning an <strong>Azure SQL Database<\/strong> you can choose to provision a demo database, <em>AdventureWorksLT<\/em>. Let&#8217;s start with one.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-92874\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/11\/QHHint01.png\" alt=\"\" width=\"701\" height=\"150\" \/><\/p>\n<h3>\nSecond Step: Creating a view to replate spt_values<\/h3>\n<p>We need to make the tables bigger for the example. Many years ago, Adam Machanic created a script called <a href=\"http:\/\/dataeducation.com\/thinking-big-adventure\/\">MakeBigAdventure.sql<\/a>. The script create two tables inside the <em>Adventureworks<\/em> database, <em>Bigproduct<\/em> and <em>BigTransactionHistory<\/em>.<\/p>\n<p>The script was made to work on <em>AdventureWorks<\/em> in a <strong>SQL Server<\/strong> on premises. It uses the table <em>master..spt_values<\/em> to randomize the records.<\/p>\n<p>On <strong>Azure SQL<\/strong>, we don&#8217;t have access to the <em>master..spt_values<\/em> table, so we need to replace it with something else. We can create a view for this purpose. The code of the view will be the following:<\/p>\n<div><span style=\"font-family: Courier New; font-size: 10pt;\"> <span style=\"color: blue;\">CREATE<\/span>\u00a0<span style=\"color: blue;\">VIEW<\/span>\u00a0<span style=\"color: maroon;\">dbo<\/span><span style=\"color: silver;\">.<\/span><span style=\"color: #8000ff;\">spt_values<\/span> <br \/>\n<span style=\"color: blue;\">AS<\/span> <br \/>\n\u00a0\u00a0<span style=\"color: blue;\">WITH<\/span>\u00a0<span style=\"color: maroon;\">int1<\/span><span style=\"color: maroon;\">(<\/span><span style=\"color: maroon;\">z<\/span><span style=\"color: maroon;\">)<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">AS<\/span>\u00a0<span style=\"color: maroon;\">(<\/span><span style=\"color: blue;\">SELECT<\/span>\u00a0<span style=\"color: black;\">0<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">UNION<\/span>\u00a0<span style=\"color: blue;\">ALL<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">SELECT<\/span>\u00a0<span style=\"color: black;\">0<\/span><span style=\"color: maroon;\">)<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">int2<\/span><span style=\"color: maroon;\">(<\/span><span style=\"color: maroon;\">z<\/span><span style=\"color: maroon;\">)<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">AS<\/span>\u00a0<span style=\"color: maroon;\">(<\/span><span style=\"color: blue;\">SELECT<\/span>\u00a0<span style=\"color: black;\">0<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">FROM<\/span>\u00a0\u00a0\u00a0<span style=\"color: maroon;\">int1<\/span>\u00a0<span style=\"color: maroon;\">a<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">CROSS<\/span>\u00a0<span style=\"color: blue;\">JOIN<\/span>\u00a0<span style=\"color: maroon;\">int1<\/span>\u00a0<span style=\"color: maroon;\">b<\/span><span style=\"color: maroon;\">)<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">int4<\/span><span style=\"color: maroon;\">(<\/span><span style=\"color: maroon;\">z<\/span><span style=\"color: maroon;\">)<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">AS<\/span>\u00a0<span style=\"color: maroon;\">(<\/span><span style=\"color: blue;\">SELECT<\/span>\u00a0<span style=\"color: black;\">0<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">FROM<\/span>\u00a0\u00a0\u00a0<span style=\"color: maroon;\">int2<\/span>\u00a0<span style=\"color: maroon;\">a<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">CROSS<\/span>\u00a0<span style=\"color: blue;\">JOIN<\/span>\u00a0<span style=\"color: maroon;\">int2<\/span>\u00a0<span style=\"color: maroon;\">b<\/span><span style=\"color: maroon;\">)<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">int8<\/span><span style=\"color: maroon;\">(<\/span><span style=\"color: maroon;\">z<\/span><span style=\"color: maroon;\">)<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">AS<\/span>\u00a0<span style=\"color: maroon;\">(<\/span><span style=\"color: blue;\">SELECT<\/span>\u00a0<span style=\"color: black;\">0<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">FROM<\/span>\u00a0\u00a0\u00a0<span style=\"color: maroon;\">int4<\/span>\u00a0<span style=\"color: maroon;\">a<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">CROSS<\/span>\u00a0<span style=\"color: blue;\">JOIN<\/span>\u00a0<span style=\"color: maroon;\">int4<\/span>\u00a0<span style=\"color: maroon;\">b<\/span><span style=\"color: maroon;\">)<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">int16<\/span><span style=\"color: maroon;\">(<\/span><span style=\"color: maroon;\">z<\/span><span style=\"color: maroon;\">)<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">AS<\/span>\u00a0<span style=\"color: maroon;\">(<\/span><span style=\"color: blue;\">SELECT<\/span>\u00a0<span style=\"color: blue;\">TOP<\/span>\u00a0<span style=\"color: black;\">2048<\/span>\u00a0<span style=\"color: black;\">0<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">FROM<\/span>\u00a0\u00a0\u00a0<span style=\"color: maroon;\">int8<\/span>\u00a0<span style=\"color: maroon;\">a<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">CROSS<\/span>\u00a0<span style=\"color: blue;\">JOIN<\/span>\u00a0<span style=\"color: maroon;\">int4<\/span>\u00a0<span style=\"color: maroon;\">b<\/span><span style=\"color: maroon;\">)<\/span> <br \/>\n\u00a0\u00a0<span style=\"color: blue;\">SELECT<\/span>\u00a0<span style=\"color: fuchsia; font-style: italic;\">Cast<\/span>\u00a0<span style=\"color: maroon;\">(<\/span><span style=\"color: blue;\">NULL<\/span>\u00a0<span style=\"color: blue;\">AS<\/span>\u00a0<span style=\"color: black; font-style: italic;\">NVARCHAR<\/span><span style=\"color: maroon;\">(<\/span><span style=\"color: black;\">35<\/span><span style=\"color: maroon;\">)<\/span><span style=\"color: maroon;\">)<\/span>\u00a0<span style=\"color: maroon;\">[name]<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #ff0080; font-weight: bold;\">Row_number<\/span><span style=\"color: maroon;\">(<\/span><span style=\"color: maroon;\">)<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">OVER<\/span>\u00a0<span style=\"color: maroon;\">(<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">ORDER<\/span>\u00a0<span style=\"color: blue;\">BY<\/span>\u00a0<span style=\"color: maroon;\">z<\/span><span style=\"color: maroon;\">)<\/span>\u00a0<span style=\"color: silver;\">&#8211;<\/span>\u00a0<span style=\"color: black;\">1<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">AS<\/span>\u00a0<span style=\"color: maroon;\">[number]<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: fuchsia; font-style: italic;\">Cast<\/span>\u00a0<span style=\"color: maroon;\">(<\/span><span style=\"color: red;\">&#8216;P&#8217;<\/span>\u00a0<span style=\"color: blue;\">AS<\/span>\u00a0<span style=\"color: black; font-style: italic;\">NCHAR<\/span><span style=\"color: maroon;\">(<\/span><span style=\"color: black;\">3<\/span><span style=\"color: maroon;\">)<\/span><span style=\"color: maroon;\">)<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">[type]<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: fuchsia; font-style: italic;\">Cast<\/span>\u00a0<span style=\"color: maroon;\">(<\/span><span style=\"color: blue;\">NULL<\/span>\u00a0<span style=\"color: blue;\">AS<\/span>\u00a0<span style=\"color: black; font-style: italic;\">INT<\/span><span style=\"color: maroon;\">)<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">[low]<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: fuchsia; font-style: italic;\">Cast<\/span>\u00a0<span style=\"color: maroon;\">(<\/span><span style=\"color: blue;\">NULL<\/span>\u00a0<span style=\"color: blue;\">AS<\/span>\u00a0<span style=\"color: black; font-style: italic;\">INT<\/span><span style=\"color: maroon;\">)<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">[high]<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: black;\">0<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">[status]<\/span> <br \/>\n\u00a0\u00a0<span style=\"color: blue;\">FROM<\/span>\u00a0\u00a0\u00a0<span style=\"color: maroon;\">int16<\/span>\u00a0 <\/span><\/div>\n<p>\nOriginal link: <a href=\"https:\/\/devio.wordpress.com\/2018\/06\/03\/generating-a-range-of-numbers-and-dates-in-t-sql\/\">https:\/\/devio.wordpress.com\/2018\/06\/03\/generating-a-range-of-numbers-and-dates-in-t-sql\/<\/a><\/p>\n<h3>Third Step: Fix the script to work with AdventureWorksLT<\/h3>\n<p><em>AdventureWorks<\/em> has the schema <em>Product<\/em>, while <em>AdventureWorksLT<\/em> has the shema <em>SalesLT<\/em>. You need to replace the <em>Product<\/em> schema by <em>SalesLT<\/em>. A simple find\/replace solves the problem.<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-92875\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/11\/QHHint02.png\" alt=\"\" width=\"529\" height=\"153\" \/><\/p>\n<p>&nbsp;<\/p>\n<h3>Fourth Step: Fix the name of spt_values in the script<\/h3>\n<p>A simple replace from <em>master..spt_values<\/em> to <em>dbo.spt_values<\/em> will do the work.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-92876\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/11\/QHHINT03.png\" alt=\"\" width=\"526\" height=\"144\" \/><\/p>\n<h3>Fifth Step: Create an Index<\/h3>\n<p>Let&#8217;s create an index over a field that we know will have an uneven distribution and due to that will cause the parameter sniffing problem.<\/p>\n<p>You can use the following statement:<\/p>\n<div><span style=\"font-family: Courier New; font-size: 10pt;\"> <span style=\"color: blue;\">CREATE<\/span>\u00a0<span style=\"color: blue;\">NONCLUSTERED<\/span>\u00a0<span style=\"color: blue;\">INDEX<\/span>\u00a0<span style=\"color: maroon;\">indprice<\/span> <br \/>\n\u00a0\u00a0<span style=\"color: blue;\">ON<\/span>\u00a0<span style=\"color: maroon;\">[dbo]<\/span><span style=\"color: silver;\">.<\/span><span style=\"color: maroon;\">[BigProduct]<\/span>\u00a0<span style=\"color: maroon;\">(<\/span><span style=\"color: maroon;\">[listprice]<\/span><span style=\"color: maroon;\">)<\/span> <\/p>\n<p><span style=\"color: maroon;\">go<\/span>\u00a0 <\/span><\/div>\n<h2>\nEstablishing the problem<\/h2>\n<p>This is the same problem describe on the article <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/database-administration-sql-server\/query-store-parameterization-problems\/\">Query Store and Parameterization Problems<\/a>, but we will use a different solution.<\/p>\n<p>Let&#8217;s create a stored procedure which causes the parameterization problem. The procedure code is below:<\/p>\n<div><span style=\"font-family: Courier New; font-size: 10pt;\"> <span style=\"color: blue;\">CREATE<\/span>\u00a0<span style=\"color: blue;\">PROCEDURE<\/span>\u00a0<span style=\"color: #ff0080; font-weight: bold;\">Filterprice<\/span>\u00a0<span style=\"color: #8000ff;\">@listprice<\/span>\u00a0<span style=\"color: black; font-style: italic;\">NUMERIC<\/span><span style=\"color: maroon;\">(<\/span><span style=\"color: black;\">15<\/span><span style=\"color: silver;\">,<\/span>\u00a0<span style=\"color: black;\">2<\/span><span style=\"color: maroon;\">)<\/span> <br \/>\n<span style=\"color: blue;\">AS<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">SELECT<\/span>\u00a0<span style=\"color: silver;\">*<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">FROM<\/span>\u00a0\u00a0\u00a0<span style=\"color: maroon;\">dbo<\/span><span style=\"color: silver;\">.<\/span><span style=\"color: maroon;\">bigproduct<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">WHERE<\/span>\u00a0\u00a0<span style=\"color: maroon;\">listprice<\/span>\u00a0<span style=\"color: silver;\">=<\/span>\u00a0<span style=\"color: #8000ff;\">@listprice<\/span>\u00a0 <\/span><\/div>\n<p>If you check the estimated execution plan of the code below, you will notice each procedure execution has a different query plan. This happens because the distribution of values in the field is not even. Some values appear way more frequently than others. The use of <strong>With Recompile<\/strong>\u00a0will ensure the plans of these executions will not be stored in the cache<\/p>\n<p>&nbsp;<\/p>\n<div><span style=\"font-family: Courier New; font-size: 10pt;\"> <span style=\"color: blue;\">EXEC<\/span>\u00a0<span style=\"color: #ff0080; font-weight: bold;\">Filterprice<\/span> <br \/>\n\u00a0\u00a0<span style=\"color: black;\">9.99<\/span>\u00a0<span style=\"color: blue;\">WITH<\/span>\u00a0<span style=\"color: maroon;\">recompile<\/span> <br \/>\n<\/span><\/div>\n<div>\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-92932\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/11\/QHHINT04.png\" alt=\"\" width=\"777\" height=\"374\" \/><\/div>\n<div><span style=\"font-family: Courier New; font-size: 10pt;\"><br \/>\n<span style=\"color: blue;\">EXEC<\/span>\u00a0<span style=\"color: #ff0080; font-weight: bold;\">Filterprice<\/span> <br \/>\n\u00a0\u00a0<span style=\"color: black;\">337.22<\/span>\u00a0<span style=\"color: blue;\">WITH<\/span>\u00a0<span style=\"color: maroon;\">recompile<\/span>\u00a0<\/span><\/div>\n<div>\u00a0<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-92933\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/11\/QHHINT05.png\" alt=\"\" width=\"603\" height=\"295\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>Causing the problem<\/h2>\n<div><span style=\"font-family: Courier New; font-size: 10pt;\">\u00a0 <\/span><\/div>\n<p>The result of the execution of the queries again, without using the <strong>With Recompile<\/strong>\u00a0is both queries will be using the same plan, which will be wrong for one of them.<\/p>\n<p>&nbsp;<\/p>\n<div><span style=\"font-family: Courier New; font-size: 10pt;\"> <span style=\"color: blue;\">EXEC<\/span>\u00a0<span style=\"color: #ff0080; font-weight: bold;\">Filterprice<\/span> <br \/>\n\u00a0\u00a0<span style=\"color: black;\">9.99<\/span> <\/p>\n<p><span style=\"color: blue;\">EXEC<\/span>\u00a0<span style=\"color: #ff0080; font-weight: bold;\">Filterprice<\/span> <br \/>\n\u00a0\u00a0<span style=\"color: black;\">337.22<\/span>\u00a0 <\/span><\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-92934\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/11\/QHHINT06.png\" alt=\"\" width=\"629\" height=\"344\" \/><\/p>\n<p>\nWhen one of these procedures is executed without the recompile option, the plan will be included in the query plan cache. The next execution will use the same plan again, causing a problem, because the plan may not be the best choice to the value.<\/p>\n<p>On the original article, we solved the problem using a plan guide to force the recompile of the query. Let&#8217;s solve the problem this time using Query Store Hints.<\/p>\n<h2>\nUsing Query Store Hints to solve the problem<\/h2>\n<p>The Query Store hints are applied over the queries. We need to discover the id of this query inside query store. The following statement can do the work:<\/p>\n<div><span style=\"font-family: Courier New; font-size: 10pt;\"> <span style=\"color: blue;\">SELECT<\/span>\u00a0<span style=\"color: maroon;\">query_sql_text<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">q<\/span><span style=\"color: silver;\">.<\/span><span style=\"color: maroon;\">query_id<\/span> <br \/>\n<span style=\"color: blue;\">FROM<\/span>\u00a0\u00a0\u00a0<span style=\"color: maroon;\">sys<\/span><span style=\"color: silver;\">.<\/span><span style=\"color: maroon;\">query_store_query_text<\/span>\u00a0<span style=\"color: maroon;\">qt<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">INNER<\/span>\u00a0<span style=\"color: blue;\">JOIN<\/span>\u00a0<span style=\"color: maroon;\">sys<\/span><span style=\"color: silver;\">.<\/span><span style=\"color: maroon;\">query_store_query<\/span>\u00a0<span style=\"color: maroon;\">q<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">ON<\/span>\u00a0<span style=\"color: maroon;\">qt<\/span><span style=\"color: silver;\">.<\/span><span style=\"color: maroon;\">query_text_id<\/span>\u00a0<span style=\"color: silver;\">=<\/span>\u00a0<span style=\"color: maroon;\">q<\/span><span style=\"color: silver;\">.<\/span><span style=\"color: maroon;\">query_text_id<\/span> <br \/>\n<span style=\"color: blue;\">WHERE<\/span>\u00a0\u00a0<span style=\"color: maroon;\">query_sql_text<\/span>\u00a0<span style=\"color: blue;\">LIKE<\/span>\u00a0<span style=\"color: red;\">N&#8217;%bigproduct%&#8217;<\/span> <br \/>\n<span style=\"color: maroon;\">go<\/span>\u00a0 <\/span><\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-92935\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/11\/QHHint07-1.png\" alt=\"\" width=\"625\" height=\"88\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Even the query being inside the stored procedure, it will be individually recorded in query store. Once we know the id of the query, we can make the application of the query hint using a stored procedure:<\/p>\n<div><span style=\"font-family: Courier New; font-size: 10pt;\"> <span style=\"color: blue;\">EXEC<\/span>\u00a0<span style=\"color: #ff0080; font-weight: bold;\">Sp_query_store_set_hints<\/span> <br \/>\n\u00a0\u00a0<span style=\"color: #8000ff;\">@query_id<\/span><span style=\"color: silver;\">=<\/span><span style=\"color: black;\">1<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0<span style=\"color: #8000ff;\">@value<\/span>\u00a0<span style=\"color: silver;\">=<\/span>\u00a0<span style=\"color: red;\">N&#8217;OPTION(RECOMPILE)&#8217;<\/span><span style=\"color: silver;\">;<\/span> <\/p>\n<p><span style=\"color: maroon;\">go<\/span>\u00a0<\/span><\/div>\n<div>\u00a0<\/div>\n<div>Execute the queries again and now each one will have the best plan according the parameter. We also have an additional benefit in comparison to other solutions, such as setting the procedure as <strong>WITH RECOMPILE<\/strong> : Only a single query is being recompiled, not the entire procedure.<\/div>\n<h2>\nMonitoring<\/h2>\n<p>Once you decide to apply query store hints, there are some monitoring tasks you need to execute:<\/p>\n<ul>\n<li>You need to monitor the hints. In case of a failure in a hint, you need to react to that.<\/li>\n<li>You need to monitor query regressions. If a hint is not needed anymore, you can suffer from a query regression and this will appear as part of the monitoring.<\/li>\n<\/ul>\n<p>The following query can be used to monitor the hints:<\/p>\n<div><span style=\"font-family: Courier New; font-size: 10pt;\"> <span style=\"color: blue;\">SELECT<\/span>\u00a0<span style=\"color: maroon;\">query_hint_id<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">query_id<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">query_hint_text<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">last_query_hint_failure_reason<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">last_query_hint_failure_reason_desc<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">query_hint_failure_count<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">source<\/span><span style=\"color: silver;\">,<\/span> <br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: maroon;\">source_desc<\/span> <br \/>\n<span style=\"color: blue;\">FROM<\/span>\u00a0\u00a0\u00a0<span style=\"color: maroon;\">sys<\/span><span style=\"color: silver;\">.<\/span><span style=\"color: maroon;\">query_store_query_hints<\/span><span style=\"color: silver;\">;<\/span> <\/p>\n<p><span style=\"color: maroon;\">go<\/span>\u00a0 <\/span><\/div>\n<h2>The Future<\/h2>\n<p><strong>SQL Server 2022<\/strong> is bringing many new optimization features. They are becoming more intelligent and being built over previous existing features. Some of the new optimization features will be automatically creating query store hints.<\/p>\n<h2>Conclusion<\/h2>\n<p>The <strong>SQL Server<\/strong> optimization features are becoming more intelligent on each version. Each new optimization feature, however, brings new and more advanced needs for monitoring.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dennes Torres explains how Query Store hints work in Azure SQL Database and Managed Instance.&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[136322,145785,4151],"coauthors":[6810],"class_list":["post-92867","post","type-post","status-publish","format-standard","hentry","category-blogs","tag-azure-sql","tag-query-store","tag-sql-server"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/92867","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=92867"}],"version-history":[{"count":12,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/92867\/revisions"}],"predecessor-version":[{"id":94190,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/92867\/revisions\/94190"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=92867"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=92867"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=92867"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=92867"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}