Query Store use cases

Query Store is a very useful feature and can help you to identify and solve some performance problems, but also help you to learn about your workload and to be more familiar with it.

The main use cases are related to issues caused by a changed execution plan. Complex queries can have many potential execution plans and some of them can be performant, while some others lead to serious performance problems. The Query Optimizer does a great job when it generates execution plans but sometimes it comes up with a suboptimal plan. It is possible that two, totally different execution plans have similar costs. When a complex query has a good plan, the next plan for the same query can perform badly. The next plan might be generated when the old plan is not in the cache anymore. This happens when SQL Server is upgrading to a new version, when cumulative update or Service Pack is installed, when patching is performed, when a failover happens, and also when a new application or service version is deployed. In all these cases, when a new plan performs badly, Query Store can help not only for identifying but also to find a solution or a workaround for the problem.

SQL Server version upgrades and patching

The main use case, and most probably the one that triggered introducing of this feature, is upgrading to a new SQL Server version. An upgrade is never a trivial action, and it brings improvements (that's the reason why we upgrade, right?), but sometimes also brings regressions. These regressions are not always predictable and it happens often that companies do not perform a full upgrade to the latest SQL Server version, but leave the most important or most volatile database in the old compatibility mode. This means execution plans will use the logic, rules, and algorithms from the previous database version. By taking this approach, you can reduce the risk of performance regression, but you will not be able to use some of the new features because they are available only in the latest compatibility mode. In my experience, after changes in the Cardinality Estimator in SQL Server 2014, more than 50% of companies did not upgrade all large and volatile databases to its compatibility mode 120 because of significant regressions. Most of the queries perform well, but some of them got different, sub-optimal execution plans and fixing them on production systems would be too expensive and risky.

Query Store can help you to perform upgrades without worrying about issues with different plans in the new version. It can easily and quickly identify issues with execution plans and offer you an option to force the old plan in case of regression, without a big impact to the production workload.

Note

In measurements and tests that I have performed, I could not detect a significant impact of Query Store activities to the database workload. I would estimate that the Query Store impact is roughly 3-5% of server resources.

A typical scenario for SQL Server version upgrade follows:

  • Upgrade SQL Server to the latest version (SQL Server 2016 Service Pack 1), but leave all user databases in the old compatibility mode.
  • Enable and configure Query Store.
  • Let Query Store work and collect information about your representative workload.
  • Change compatibility level to the latest one (130).
  • Check Regressed Queries report in Query Store.
  • Force old plans for regressed queries.
  • Query Store will let you fix the problems by choosing the old plan. However, as mentioned earlier, this might not be a final solution and it is good idea to analyze why regression happened and to try to tune the query. Of course, this could be time and resource consuming and it is better to do this later, when you have enough time, than when under pressure, at the time when problems occur on the production system.

Application and service releases, patching, failovers, and cumulative updates

In all these cases, Query Store can help you to identify issues after the actions and to fix problems caused by changed execution plans very quickly, efficiently, and without risking business applications. A typical scenario is:

  • Ensure that Query Store is enabled and configured.
  • Let Query Store work and capture information about your representative workload.
  • Perform the install action. This can be one of these actions.
  • Server failover.
  • Installing SQL Server Service Pack.
  • Installing SQL Server Cumulative Update.
  • Upgrade hardware configuration.
  • Operating system and network patching.
  • Application and service deployment.
  • Let Query Store collect information about queries and plans.
  • Run Regressed Queries and Top Resources Consuming Query reports
  • Query Store will let you fix the problems by choosing the old plan. It is good idea to analyze why regression happened, but it is better to do this later, when you have enough time.

Identifying ad hoc queries

You can use Query Store to identify ad hoc workloads, which are typically characterized by a relatively large number of different queries executed very rarely, and usually only once. Use the following query to identify all queries that are executed exactly once:

SELECT p.query_id 
FROM sys.query_store_plan p 
INNER JOIN sys.query_store_runtime_stats s ON p.plan_id = s.plan_id 
GROUP BY p.query_id 
HAVING SUM(s.count_executions) = 1; 

Identifying unfinished queries

In the section, Query Store in Action, you saw that Query Store does not capture runtime statistics only for successfully executed queries. When query execution is aborted by the caller or end with an exception, this info is not stored to server cache, but Query Store collects that info too. This can help you to easily identify queries with an incomplete execution process.

To see an example, you first need to clean-up info that was captured in the previous sections of this chapter:

ALTER DATABASE Mila SET QUERY_STORE CLEAR ALL; 
ALTER DATABASE Mila SET QUERY_STORE = OFF; 
ALTER DATABASE Mila   
SET QUERY_STORE = ON    
    (   
      OPERATION_MODE = READ_WRITE    
    , DATA_FLUSH_INTERVAL_SECONDS = 2000       
    , INTERVAL_LENGTH_MINUTES = 1    
    );  

You should also ensure that the latest compatibility mode is applied:

ALTER DATABASE Mila SET COMPATIBILITY_LEVEL = 130; 

Now, you can execute the same query as you did in the section Query Store in Action:

SELECT * FROM dbo.Orders WHERE status IN (0,2); 
GO 100 

You should execute the query, then click the cancel executing query button in the SQL Server management studio, then click again to execute it in order to simulate the execution and query abortion.

In addition to this you should execute the following query, too:

SELECT Status/ (SELECT COUNT(*) FROM dbo.Orders WHERE Status IN (0, 2)) FROM dbo.Orders WHERE id = 1; 

This query will not be successfully executed; it will raise a Divide by zero exception. Now, you can check what Query Store has captured. To do this run the following code:

SELECT * FROM sys.query_store_runtime_stats;  

In the following screenshot you can see two entries for your initial query (regular executed and aborted) and also an entry for the query with the Divide by zero exception:

Identifying unfinished queries

Figure 9-23. Identifying unfinished queries by using Query Store

As you can see, by using Query Store you can easily identify started but not executed queries in your database.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset