当前位置:网站首页>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 】:
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 :
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 :
At the same time, the inconsistency can be seen in the attribute :
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 .
边栏推荐
- 二叉樹初始化代碼
- JVM GC (V)
- JS merge multiple string arrays to maintain the original order and remove duplicates
- Differences between XAML and XML
- [JVM series 4] common JVM commands
- Explain tool and index optimization (II)
- Use of jstack
- Complex network analysis capability based on graph database
- Installing the IK word breaker
- MMAP usage in golang
猜你喜欢
Neil eifrem, CEO of neo4j, interprets the chart data platform and leads the development of database in the next decade
Wechat applet coordinate location interface usage (II) map interface
Graph data modeling tool
Parallel one degree relation query
QML connecting to MySQL database
Use cypher to get the tree of the specified structure
Binary tree initialization code
【 enregistrement pytorch】 paramètre et tampon des variables pytorch. Self. Register Buffer (), self. Register Paramètre ()
On the career crisis of programmers at the age of 35
Vscode liveserver use_ Liveserver startup debugging
随机推荐
Understanding of intermediatelayergetter
PHP import classes in namespace
JMeter quick start
MySQL index optimization (4)
Few-shot Unsupervised Domain Adaptation with Image-to-Class Sparse Similarity Encoding
Use of jstack
Beginner development process_ Project development FAQs
. Net compact Framework2.0 wince intelligent device development project experience sharing Net drag space advanced
2021-08-30 distributed cluster
C method parameter: out
Querywrapper constructor method
C 10 new features_ C 10 new features
Mongodb distributed cluster deployment process
[JVM Series 2] runtime data area
Figure data * reconstruction subgraph
Transaction processing in PDO
Filters in PHP
Simple use of qtreeview of QT (including source code + comments)
关于复合函数的极限问题
Applet image component long press to identify supported codes