Query Data Store Data

Home / SQL Server 2016 / Query Data Store Data

The data in the Query Data Store is what makes all the magic happen. From collecting the aggregate performance metrics of a query to the various plans in use by that query to being able to force a plan, it’s all controlled by the data within the Query Data Store system tables.

The Question

When I was presenting on this topic at the PASS Summit a few weeks ago, one great question came up (great question = answer is “I don’t know”), well, I defaulted to an “I don’t know” answer, but my guess was, “No.” The question was: can you take a plan from one server, let’s say a test server, export it in some way, and then import it to production? In this manner, you ensure that a plan you like gets into production without having to clear the plan from cache & generate a plan by running the query.

Great idea.

However, I knew that the Query Data Store information is all stored in system tables. You can’t directly modify system tables in SQL Server (well, not any more. In old versions prior to 2005, you could. Ah the joy of REALLY screwing up a database). However, I tested it. You won’t be shocked to find out, nope. you can’t.

So What Can You Do?

You have a number of data manipulation options. Since you can query the data store, obviously, you can export that data and store it elsewhere. When you backup a database, the Query Data Store data gets backed up. You can also directly manipulate the data using the procedures listed here to flush the store, remove a particular query or plan, or reset the performance statistics.

That’s about it. In it’s current incarnation, there’s not much in the way of direct manipulation of the data in the query store. It’s just like any other system table in that way.

Just Imagine

I’d love to see them add the ability to upload, or import, an execution plan. Imagine the scenario where you have sharded your database across multiple servers, or, if you’re in Azure SQL Database, multiple databases. You identify a particular execution plan that’s going to work well for all these instances. Wouldn’t it be great to be able to import that plan and force all the various servers to use it, all programmatically? Heck yes.

However, we’re not there today.


I love talking performance tuning. In fact, I’ll be doing an all day seminar on execution plans and query tuning before SQLSaturday Providence in Rhode Island, December 2016, therefore, if you’re interested, sign up here.

5 Comments

  • One point that I sort of missed here is that the new functionality in SQL Server 2016 that lets you clone a database through DBCC CLONEDATBASE does copy the Query Data Store data. You just can’t reuse it in the way that was proposed, literally moving a plan from one server to another or one database to another in order to reuse it.

    I have a blog post coming out on DBCC CLONEDATABASE on Monday.

  • Hi Grant,

    Just like you I would love to be able to move execution plans between Query Stores. So for a few weeks now I have been working on something that allows you to “replay” queries from one database to another based on execution plans. Basically this recreates the plan by executing the query on another database. While it might not be perfect yet this might be helpful for you as well.
    The code is available on GitHub: https://github.com/Evdlaar/QueryStoreReplay.

  • Thanks for sharing. Nice bit of code. As soon as you said it I assumed you must be walking the XML for the compile time values. Nice to see I was correct.

    That is useful. I still want export/import or something similar, but this is good.

    I assume you’ve looked at DBCC CLONEDATABASE too?

  • Yeah I did, love it!
    Was secretly hoping they would add a parameter to include Query Store data when it got released on 2016, really happy they did.
    Even though the Replay script will never be able to 1-on-1 export and import the Execution plan, I am working on writing some code that can check if the identical plan was generated and measure the performance differences between source and target database automagically :-).

OK, fine, but what do you think?