当前位置:网站首页>Azure SQL db/dw series (14) -- using query store (3) -- common scenarios

Azure SQL db/dw series (14) -- using query store (3) -- common scenarios

2022-06-13 03:21:00 Hair dung coating wall

This paper belongs to Azure SQL DB/DW series
Last article :Azure SQL DB/DW series (13)—— Use Query Store(2)—— Report Introduction (2)
This article continues on how to use Query Store Common scenarios

Preface

  Query Store There are many uses , Based on its collection function , It is very suitable as the performance baseline of the server . A performance baseline is a standard , Used to determine whether the server has performance problems . So professional database and server operation and maintenance , A reasonable performance baseline should be established .
   When enabled Query Store after , You can collect data from a time interval , This interval is based on INTERVAL_LENGTH_MINUTES And decide . It can be 1,5,10,15,60 and 1440 minute .
   The reports commonly used for performance baseline are 【 Overall resource consumption 】:
 Insert picture description here
   Through this report , You can see that in this time interval , Resource usage of server and database . For example, above ( The same is to borrow the online map ), The activity was very low two days ago , These two days are weekends , So we can guess from the load that this is an application system for weekday use . At the same time, it is observed that whenever it lasts for a long time , Logic reading is also very high , This time you can jump to 【 The most resource consuming queries 】 View specific queries in the report .
   We can also use the following statement to view the recent 10 The longest duration in a day 10 A query :

SELECT TOP 10 qt.query_sql_text
	,q.query_id
	,so.name
	,so.type
	,SUM(rs.count_executions * rs.avg_duration) AS 'Total Duration'
FROM sys.query_store_query_text qt
INNER JOIN sys.query_store_query q ON qt.query_text_id = q.query_text_id
INNER JOIN sys.query_store_plan p ON q.query_id = p.query_id
INNER JOIN sys.query_store_runtime_stats rs ON p.plan_id = rs.plan_id
INNER JOIN sys.query_store_runtime_stats_interval rsi ON rsi.runtime_stats_interval_id = rs.runtime_stats_interval_id
INNER JOIN sysobjects so ON so.id = q.object_id
WHERE rsi.start_time >= DATEADD(DAY, - 10, GETUTCDATE())
GROUP BY qt.query_sql_text
	,q.query_id
	,so.name
	,so.type
ORDER BY SUM(rs.count_executions * rs.avg_duration_time) DESC

   But with the development of Globalization , A lot of time has been spent on UTC To store , For example, Beijing time is UTC+8. So when using this script, you should pay attention to the conversion .
   In addition, you can also analyze queries that have planned regression 、 Discover resource consumption 、 Comparison after modifying the configuration , Actually, in my opinion ,Query Store It can be well used for most reports .

Use Query Store Create performance baseline

   First of all, we need to know Query Store What has been collected , What do we need , What is to be collected with additional tools .
   In addition, before collecting and developing baselines , Remember to empty first Query Store To avoid data confusion . Can pass GUI→ database → attribute →【 Query storage 】 In the interface 【 Empty Query Store】 Button to clear . It can also be executed :

USE [<Database>]
GO
EXEC sys.sp_query_store_flush_db;

   After emptying , You can start running the load , The best is the real environment .
   After collecting for a certain time , It usually depends on your collection interval , such as 15 minute , that 15 Minutes later, you can stop or start a new round of collection to understand the changes .
   The common use is to know what happened in a short period of time, especially at night , Because it is often more difficult to find out what has happened .
   But with Query Store, Looking back at a certain period of time in the past is very simple .
   For example. 【 The most resource consuming queries 】 Configuration in , Choose a specific time :
 Insert picture description here

Query to find regression

   As mentioned in the previous article , Regression query makes the same query performance different ( Usually worse ), The reason for regression may be the update of statistical information , Changes in data distribution , Index changes and so on . Because the optimizer will select a better execution plan according to the actual situation , This often leads to query regression . It can be used at this time 【 Regression query 】 report form .
   In this report , You can select two plans in the upper right window , Use a query with two plans , And use the compare plan button in the upper right corner . Then the difference part of the execution plan will be highlighted :
 Insert picture description here
   At the same time, the inconsistency can be seen in the attribute :
 Insert picture description here

T-SQL Query information

  Query Store In essence, it is mainly storage , And display 7 Default report in , But there is still a lot of data that has not been used , You can use some at this time T-SQL Query to find its value , Here are a few queries collected on the Internet , For reader's reference :

-- Total number of query text 
SELECT COUNT(*) AS CountQueryTextRows
FROM sys.query_store_query_text;

-- Total number of queries 
SELECT COUNT(*) AS CountQueryRows
FROM sys.query_store_query;

-- Unique query ( That is, different queries ) The number of 
SELECT COUNT(DISTINCT query_hash) AS CountDifferentQueryRows
FROM sys.query_store_query;

-- Total number of implementation plans 
SELECT COUNT(*) AS CountPlanRows
FROM sys.query_store_plan;

-- Number of different execution plans 
SELECT COUNT(DISTINCT query_plan_hash) AS CountDifferentPlanRows
FROM sys.query_store_plan;

   If you find that CountQueryRows and CountDifferentQueryRows perhaps
CountPlanRows and CountDifferentPlansRows There are differences between , It means that you have some similar statements running , It may be appropriate to parameterize .

-- In the database 10 Recently executed queries 
SELECT
       TOP 10 qt.query_sql_text, q.query_id, qt.query_text_id, 
       p.plan_id, rs.last_execution_time
FROM sys.query_store_query_text   qt 
JOIN sys.query_store_query   q ON qt.query_text_id   = q.query_text_id   
JOIN sys.query_store_plan   p ON q.query_id   = p.query_id 
JOIN sys.query_store_runtime_stats   rs ON p.plan_id   = rs.plan_id
ORDER BY rs.last_execution_time   DESC
 
-- Get the execution times of each query 
SELECT
       q.query_id, qt.query_text_id, 
       qt.query_sql_text, 
       SUM(rs.count_executions) AS total_execution_count
FROM sys.query_store_query_text   qt 
JOIN sys.query_store_query   q ON qt.query_text_id   = q.query_text_id   
JOIN sys.query_store_plan   p ON q.query_id   = p.query_id 
JOIN sys.query_store_runtime_stats   rs ON p.plan_id   = rs.plan_id
GROUP BY q.query_id, qt.query_text_id, qt.query_sql_text
ORDER BY total_execution_count DESC
 
-- In the last hour , The longest average execution time 10 A query 
SELECT
       TOP 10 qt.query_sql_text, 
       q.query_id, qt.query_text_id, p.plan_id, 
       GETUTCDATE() AS CurrentUTCTime, 
       rs.last_execution_time,   rs.avg_duration
FROM sys.query_store_query_text   qt 
JOIN sys.query_store_query   q ON qt.query_text_id   = q.query_text_id   
JOIN sys.query_store_plan   p ON q.query_id   = p.query_id 
JOIN sys.query_store_runtime_stats   rs ON p.plan_id   = rs.plan_id
WHERE   rs.last_execution_time > DATEADD(HOUR, -1, GETUTCDATE())
ORDER BY rs.avg_duration desc
 
-- lately 24 Within hours ,10 Average physics I/O  Read the highest query 
SELECT
       TOP 10 qt.query_sql_text, 
       q.query_id, qt.query_text_id, 
       p.plan_id, rs.runtime_stats_id, 
       rsi.start_time, rsi.end_time, 
       rs.avg_physical_io_reads,   
       rs.avg_rowcount, rs.count_executions
FROM sys.query_store_query_text   qt 
JOIN sys.query_store_query   q ON qt.query_text_id   = q.query_text_id   
JOIN sys.query_store_plan   p ON q.query_id   = p.query_id 
JOIN sys.query_store_runtime_stats   rs ON p.plan_id   = rs.plan_id 
JOIN sys.query_store_runtime_stats_interval   rsi 
ON rsi.runtime_stats_interval_id =   rs.runtime_stats_interval_id
WHERE   rsi.start_time >=   DATEADD(HOUR, -24, GETUTCDATE()) 
ORDER BY rs.avg_physical_io_reads   desc
 
-- Recent performance regression ( Return to ) Query for , The condition is the past 48 The execution time has more than doubled in hours )
SELECT
       qt.query_sql_text, 
       q.query_id, 
       p1.plan_id AS plan1, 
       rs2.avg_duration AS   plan2
FROM sys.query_store_query_text   qt 
JOIN sys.query_store_query   q ON qt.query_text_id   = q.query_text_id   
JOIN sys.query_store_plan   p1 ON q.query_id   = p1.query_id   
JOIN sys.query_store_runtime_stats   rs1 ON p1.plan_id   = rs1.plan_id   
JOIN sys.query_store_runtime_stats_interval   rsi1 ON rsi1.runtime_stats_interval_id   = rs1.runtime_stats_interval_id   
JOIN sys.query_store_plan   p2 ON q.query_id   = p2.query_id   
JOIN sys.query_store_runtime_stats   rs2 ON p2.plan_id   = rs2.plan_id   
JOIN sys.query_store_runtime_stats_interval   rsi2 ON rsi2.runtime_stats_interval_id   = rs2.runtime_stats_interval_id
WHERE   rsi1.start_time >   DATEADD(HOUR, -48, GETUTCDATE()) AND
rsi2.start_time >   rsi1.start_time AND
rs2.avg_duration >   2*rs1.avg_duration
 
-- Queries with multiple execution plans 
WITH   QueryWithMultiplePlans 
AS
(
       SELECT COUNT(*) AS cnt, q.query_id 
       FROM sys.query_store_query_text qt 
       JOIN sys.query_store_query q ON   qt.query_text_id =   q.query_text_id 
       JOIN sys.query_store_plan p ON   p.query_id =   q.query_id 
       GROUP BY q.query_id HAVING COUNT(DISTINCT plan_id) > 1 
)
SELECT   q.query_id, OBJECT_NAME(object_id) AS ContainingObject,   
query_sql_text, plan_id, p.query_plan AS   plan_xml, p.last_compile_start_time, 
p.last_execution_time 
FROM QueryWithMultiplePlans   qm 
JOIN sys.query_store_query   q ON qm.query_id   = q.query_id 
JOIN sys.query_store_plan   p ON q.query_id   = p.query_id 
JOIN sys.query_store_query_text   qt ON qt.query_text_id   = q.query_text_id   
ORDER BY query_id,   plan_id

   If there is a good script in the follow-up, it will continue to be supplemented .

summary

   This paper introduces Query Store Common scenarios , As far as I'm concerned , First, it collects comprehensive data , Secondly, the preset report has been very perfect , Can handle most problems . Then after a deep understanding , You can also define some queries to meet your requirements . I don't use many scenarios in my work , So it will not be expanded for the time being . Once there is a certain amount and quality of accumulation , It will be updated in time .

原网站

版权声明
本文为[Hair dung coating wall]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202280531217637.html