导出一个SQL计划并清除Azure SQL数据库的计划缓存

如何解决导出一个SQL计划并清除Azure SQL数据库的计划缓存

我正在尝试编写一个 powershell 脚本来尝试在 Azure sql 数据库上查找前 2 个正在运行的查询,然后捕获这 2 个查询查询计划,然后释放 DBCC 缓存并在清除缓存后再次捕获这些计划并使用 sendgird 将这些计划通过电子邮件发送。

问题 1:$delta2 中存储的计划句柄不正确,与 sys.dm_exec_query_plan() 一起使用时不起作用

问题 2:如果我设法从 sql studio 获得正确的句柄并在 $delta3 中使用它们,sys.dm_exec_query_plan() 在 PowerShell 中不会给出任何响应

问题 3:Export-clixml 修改了 xml 文件,并且无法在 sql Studio 中打开。

非常感谢任何帮助。提前致谢。

$params = @{
    'Database' = 'xx'
    'ServerInstance' =  'xx'
    'Username' = 'xx'
    'Password' = 'xxx'
    'OutputsqlErrors' = $true
}
$sqlcmd= "
SELECT TOP 2
    GETDATE() runtime,*
FROM (SELECT  convert(VARCHAR(50),query_stats.query_hash,1) as query_hash,SUM(query_stats.cpu_time) 'Total_Request_cpu_Time_Ms',SUM(logical_reads) 'Total_Request_Logical_Reads',MIN(start_time) 'Earliest_Request_start_Time',COUNT(*) 'Number_Of_Requests',SUBSTRING(REPLACE(REPLACE(MIN(query_stats.statement_text),CHAR(10),' '),CHAR(13),1,256) AS" + '"Statement_Text" '+"
    FROM (SELECT req.*,SUBSTRING(ST.text,(req.statement_start_offset / 2)+1,((CASE statement_end_offset WHEN -1 THEN DATALENGTH(ST.text)ELSE req.statement_end_offset END-req.statement_start_offset)/ 2)+1) AS statement_text
        FROM sys.dm_exec_requests AS req
                CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) AS ST ) AS query_stats
    GROUP BY query_hash) AS t
ORDER BY Total_Request_cpu_Time_Ms DESC;"
$delta1 = Invoke-sqlcmd -query $sqlcmd @params -MaxCharLength 999999 
$qhash = $delta1.query_hash
$delta2 =  "select convert(VARCHAR(100),plan_handle,1) as plan_handle  from sys.dm_exec_query_stats where query_hash = $qhash"
$getplanhandle = Invoke-sqlcmd -query $delta2  @params -MaxCharLength 999999 
$getplanhandle
foreach($plan in $getplanhandle)
{
$handle = $plan.plan_handle
$delta3 = "select * from sys.dm_exec_query_plan($plan.plan_handle)"
$saveplan = Invoke-sqlcmd -query $delta3  @params -MaxCharLength 999999 
$saveplan.query_plan | export-clixml -path ./query_plan.sqlplan
}

解决方法

您很可能不需要执行其中的大部分/任何操作。从您的帖子中并不清楚您“为什么”要这样做,但我假设您只是想记录查询计划以供以后进行性能分析,因为这通常是人们想要查看计划的原因。>

好消息是,Azure SQL DB 有一项功能可以自动为您捕获大多数查询计划 - 查询存储。它将它们存储在数据库中,您可以查看一段时间内给定查询使用了哪些查询计划以及它们如何执行的完整历史记录。您可以在此处阅读更多相关信息:Query Store overview。请注意,默认情况下,查询存储垫不会捕获所有查询(对于某些类型的工作负载,它可能会使数据库不堪重负)。如果您在测试系统上执行此操作,则可以使用“全部”捕获模式来记录所有计划。

如果您正试图确定给定查询是否存在参数敏感性问题(如果带有参数的谓词的选择性发生显着变化,从而导致给定查询计划处理很少/许多不同参数值的行),您还可以在查询存储中看到此属性 - 它会为您跟踪的每个查询计划记录平方和方差。 SQL Server Management Studio 有一个很好的 UI 来帮助您导航查询存储数据。您可以阅读有关 here 的更多信息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?