查询存储功能可帮助您跟踪查询计划,运行时统计信息和查询/计划历史记录。它还可以帮助您找到回归查询。您可以快速查找包含多个计划的新查询,识别无效计划并强制制定更好的计划。
我们将在所有示例中使用最新的SQL Server 2016 CTP 2.2版。
使用“查询存储”数据库属性页启用和配置查询存储:
它也可以使用T-SQL启用:
ALTER DATABASE [DEMO_1] SET QUERY_STORE = ON;
为数据库启用查询存储后,您可以配置其他查询存储设置(可配置项以粗体显示):
单击每个属性以查看其描述。可以在官方文档找到有关每个配置选项的详细信息
https://docs.microsoft.com/en-us/sql/relational-databases/performance/monitoring-performance-by-using-the-query-store?view=sql-server-2017#Options
还可以使用T-SQL更改Query Store配置:
ALTER DATABASE [DEMO_1]
SET QUERY_STORE (OPERATION_MODE = READ_ONLY,
CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 367),
DATA_FLUSH_INTERVAL_SECONDS = 900,
INTERVAL_LENGTH_MINUTES = 60,
MAX_STORAGE_SIZE_MB = 100,
QUERY_CAPTURE_MODE = AUTO,
SIZE_BASED_CLEANUP_MODE = AUTO)
GO
我们来看看“Query Store”属性页面上提供的其他信息。
当前磁盘使用情况
此部分显示左侧的数据库大小和查询存储使用情况以及右侧的查询存储大小和用法:
请注意“查询存储”页面上的“清除查询数据”按钮。您可以使用此按钮删除查询存储的内容,或使用以下语句之一:
ALTER DATABASE [DEMO_1] SET QUERY_STORE CLEAR ALL
或
EXEC sys.sp_query_store_flush_db
在SQL Server 2016 CTP 2.2中有6个新的系统存储过程和7个与查询存储相关的目录视图,可以通过运行此查询找到:
SELECT name, type_desc FROM sys.all_objects
WHERE name LIKE '%query_store%' or name= 'query_context_settings'
你可以在这里找到存储过程的描述: https: //msdn.microsoft.com/en-us/library/dn818153.aspx和目录视图的描述:https: //msdn.microsoft.com/en-us /library/dn818149.aspx。
此外,还有19个新的扩展事件:
SSMS“查询存储”容器
启用Query Store后,数据库将在SSMS中具有新的“Query Store”容器:
您可以右键单击“Query Store”容器以查看可用选项:
或者,您可以展开容器并使用Query Store SSMS窗格:
以下为2017
top 资源消耗
大多数Query Store窗格具有类似的结构和显示选项。让我们在“Top Resource Consumers”窗格示例中查看它们:
左图中选中的sql有几个执行计划,右图中就会以不同颜色显示每个计划。
您可以将鼠标悬停在左侧或右侧图表的对象上,并查看特定query_id或plan_id的详细统计信息。
根据左侧所选的指标,细节会有所不同:
右图(4)中气泡的大小取决于总执行次数。
当您单击不同的计划((3)或(4))时,窗格(5)的底部将显示此特定plan_id的执行计划。
让我们回顾一下“top 资源消耗”窗格中的下拉菜单:
(1)可用的指标:
(2)左图 - 垂直轴:
(3)统计:
(4)左图 - 水平轴:
(5)右图(“计划摘要”)垂直轴根据左侧图表中选择的“统计”进行更改:
(6)如果您的屏幕分辨率较小,则会隐藏一些按钮。
让我们点击右侧图表上的“网格”和标题旁边的“垂直视图”,查看可用的按钮:
将“计划摘要”从图表更改为网格允许我们以表格格式查看每个计划的统计信息。
“Track Query”(1)按钮将打开“Tracked Queries”窗格。我们将在下一篇文章中查看此窗格。
“View Query”(2)将使用查询的T-SQL脚本打开新的SSMS窗口:
左侧图表上的“详细网格”按钮(3)将显示包含所有统计信息的top查询列表(显示更多列):
左侧图表上的“网格”按钮(4)显示热门查询列表,但列数将受到限制,显示的列将取决于所选的统计信息和指标:
“配置”按钮(5)允许您在一个位置配置窗格:
这是“时间间隔”选项:
如果您有多个计划的查询,可以单击左侧图表上的“比较计划”按钮,并排查看计划:
“强制计划”按钮位于执行计划部分和左侧图表下。
查询Query Store的已用大小和最大大小
SELECT current_storage_size_mb, max_storage_size_mb FROM sys.database_query_store_options;
在查询存储中查找查询的ID
SELECT q.query_id, t.query_sql_text, object_name(q.object_id) AS parent_object
FROM sys.query_store_query_text t JOIN sys.query_store_query q
ON t.query_text_id = q.query_text_id
WHERE t.query_sql_text LIKE N'%insert %db_store%'
OR object_name(q.object_id) = 'proc_1';
查找与查询关联的计划
根据查询ID(如果已知),部分查询文本或对象(视图,存储过程等)名称查找计划ID
SELECT t.query_sql_text, q.query_id, p.plan_id, object_name(q.object_id) AS parent_object
FROM sys.query_store_query_text t JOIN sys.query_store_query q
ON t.query_text_id = q.query_text_id
JOIN sys.query_store_plan p ON q.query_id = p.query_id
WHERE q.query_id = 1
-- OR t.query_sql_text LIKE N'%SELECT c1, c2 FROM dbo.db_store%'
-- OR object_name(q.object_id) = 'proc_1';
在查询存储中查找执行计划最多的前10个查询
SELECT TOP 10 t.query_sql_text, q.query_id,
object_name(q.object_id) AS parent_object,
COUNT(DISTINCT p.plan_id) AS num_of_plans
FROM sys.query_store_query_text t JOIN sys.query_store_query q
ON t.query_text_id = q.query_text_id
JOIN sys.query_store_plan p ON q.query_id = p.query_id
GROUP BY t.query_sql_text, q.query_id, object_name(q.object_id)
HAVING COUNT(DISTINCT p.plan_id) > 1
ORDER BY COUNT(DISTINCT p.plan_id) DESC
在查询存储中查找执行次数最多的TOP 10查询
SELECT TOP 10 t.query_sql_text, q.query_id,
object_name(q.object_id) AS parent_object,
SUM(s.count_executions) total_executions
FROM sys.query_store_query_text t JOIN sys.query_store_query q
ON t.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 s ON p.plan_id = s.plan_id
WHERE s.count_executions > 1 -- used to make the query faster
GROUP BY t.query_sql_text, q.query_id, object_name(q.object_id)
ORDER BY SUM(s.count_executions) DESC
查找在查询存储中受影响的行数最多的TOP 10查询
这可能有助于检查是否有返回大量行的查询
SELECT top 10 t.query_sql_text, q.query_id,
object_name(q.object_id) AS parent_object,
s.plan_id, s.avg_rowcount
FROM sys.query_store_query_text t JOIN sys.query_store_query q
ON t.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 s ON p.plan_id = s.plan_id
WHERE s.avg_rowcount > 100
ORDER BY s.avg_rowcount DESC
查找在查询存储中每次执行的编译比例最大的TOP 10查询
有时查询性能可能会受到过度重新编译的影响。使用它来查找具有大量编译的前10个查询:
WITH Query_Stats
AS
(
SELECT plan_id,
SUM(count_executions) AS total_executions
FROM sys.query_store_runtime_stats
GROUP BY plan_id
)
SELECT TOP 10 t.query_sql_text, q.query_id, p.plan_id,
s.total_executions/p.count_compiles avg_compiles_per_plan
FROM sys.query_store_query_text t JOIN sys.query_store_query q
ON t.query_text_id = q.query_text_id
JOIN sys.query_store_plan p ON q.query_id = p.query_id
JOIN Query_Stats s ON p.plan_id = s.plan_id
ORDER BY s.total_executions/p.count_compiles DESC
清理SQL Server查询存储数据
您可以使用sp_query_store_remove_plan 存储过程从查询存储中删除特定计划(计划的运行时统计信息也将被清除):
EXEC sp_query_store_remove_plan @plan_id = 1
使用 sp_query_store_reset_exec_stats存储过程,您可以删除特定计划的运行时统计信息,但将计划本身保留在Query Store:
EXEC sp_query_store_reset_exec_stats @plan_id = 1
您还可以使用sp_query_store_remove_query 存储过程从Query Store中删除整个查询 。这将从Query Store中删除相关的计划和统计信息:
EXEC sp_query_store_remove_query @query_id = 1
其他一些有用的查询可以在Microsoft MSDN网站上 找到:
您可能会发现以下列对您自己的查询很有用:
参考
https://www.mssqltips.com/sqlservertip/4009/sql-server-2016-query-store-introduction/
https://www.mssqltips.com/sqlservertip/4047/sql-server-2016-query-store-queries/