博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ssms应用程序错误_来自应用程序的查询计划与SSMS不同时的性能故障排除
阅读量:2516 次
发布时间:2019-05-11

本文共 11456 字,大约阅读时间需要 38 分钟。

ssms应用程序错误

Troubleshooting performance issues in a database is one of the main jobs of DBAs and by now most can trace the problem back to a query which is either running to slow or is causing a blocking issue on a key table. However, what is often not known is why this doesn’t cause problems in SSMS or why you don’t get the same query plan as what is inside the app. For example, in your extended event trace you see the query running longer from the application when compared to SSMS.

对数据库中的性能问题进行故障排除是DBA的主要工作之一,到目前为止,大多数人可以将问题追溯到查询,该查询运行缓慢或导致键表出现阻塞问题。 但是,通常不知道的是为什么这不会在SSMS中引起问题,或者为什么您没有得到与应用程序内部相同的查询计划。 例如,在扩展事件跟踪中,与SSMS相比,您看到查询从应用程序运行的时间更长。

This can usually be found by the execution plan from management studio being different from the one that was gathered through the application trace. The first thing to verify is that you are running the same query with the same parameters. Depending on the query parameters it is very possible to get different plans, either by using sargable vs nonsargble or even having a different data type which causes an implicit conversion.

通常可以从Management Studio的执行计划中找到与从应用程序跟踪收集的计划不同的计划。 验证的第一件事是您正在使用相同的参数运行相同的查询。 根据查询参数,非常有可能获得不同的计划,或者使用可精还是不可精,甚至具有导致隐式转换的不同数据类型。

Secondly, you will want to make sure your “set options” are configured the same as your application. To do this, you can verify your set options in your execution plans by right clicking on your select operator and choosing properties. In the window on the left you will see a section labeled Set options, once expanded you will see all the options that were used during the execution of your query.

其次,您将要确保将“设置选项”配置为与应用程序相同。 为此,您可以通过右键单击选择运算符并选择属性来验证执行计划中的设置选项。 在左侧的窗口中,您将看到标有“设置选项”的部分,展开后,您将看到在执行查询期间使用的所有选项。

These set options affect and can change your execution plans if they are different.

如果这些设置选项不同,它们会影响您的执行计划,并且可以更改它们。

This can also be found my cross applying sys.dm_exec_plan_attributes on the plan handle. Right away the integer returned can be a bit confusing as it only allows you to see if the plans have the same set options or differences. How this is calculated is by subtracting the largest value in the set option chart that you can and then working down until the number reaches zero. This will give you all the options that were enabled at runtime. These options and more details can be found on the .

也可以在计划句柄上交叉应用sys.dm_exec_plan_attributes的情况下找到。 立即返回的整数可能会有点令人困惑,因为它仅允许您查看计划是否具有相同的设置选项或差异。 计算方法是通过减去设置的选项表中的最大值,然后向下计算直到数字达到零为止。 这将为您提供在运行时启用的所有选项。 这些选项和更多详细信息可以在上找到。

As a side note, since cursors have similar set options their information can be gathered in a similar format.

附带说明,由于游标具有相似的设置选项,因此可以采用相似的格式收集其信息。

To get this information for your query run the below script, making sure to replace the SQL text in the where clause.

要获取有关查询的信息,请运行以下脚本,并确保替换where子句中SQL文本。

SELECT QueryPlan.query_plan as ExecutionPlan ,	  SqlText.text as SQLText,	  PlanAttributes.value AS SetOptionsInt,	  IIF (CAST (PlanAttributes.value as INT) & 1 = 1 , N'Enabled' , N'Disabled') as [ANSI_PADDING],	  IIF (CAST (PlanAttributes.value as INT) & 2 = 2 , N'Enabled' , N'Disabled') as [Parallel_Plan],	  IIF (CAST (PlanAttributes.value as INT) & 4 = 4 , N'Enabled' , N'Disabled') as [FORCEPLAN],	  IIF (CAST (PlanAttributes.value as INT) & 8 = 8 , N'Enabled' , N'Disabled') as [CONCAT_NULL_YIELDS_NULL],	  IIF (CAST (PlanAttributes.value as INT) & 16 = 16 , N'Enabled' , N'Disabled') as [ANSI_WARNINGS],	  IIF (CAST (PlanAttributes.value as INT) & 32 = 32 , N'Enabled' , N'Disabled') as [ANSI_NULLS],	  IIF (CAST (PlanAttributes.value as INT) & 64 = 64 , N'Enabled' , N'Disabled') as [QUOTED_IDENTIFIER],	  IIF (CAST (PlanAttributes.value as INT) & 128 = 128 , N'Enabled' , N'Disabled') as [ANSI_NULL_DFLT_ON],	  IIF (CAST (PlanAttributes.value as INT) & 256 = 256 , N'Enabled' , N'Disabled') as [ANSI_NULL_DFLT_OFF],	  IIF (CAST (PlanAttributes.value as INT) & 512 = 512 , N'Enabled' , N'Disabled') as [NoBrowseTable], -- Indicates that the plan does not use a work table to implement a FOR BROWSE operation.	  IIF (CAST (PlanAttributes.value as INT) & 1024 = 1024 , N'Enabled' , N'Disabled') as [TriggerOneRow], --Indicates that the plan contains single row optimization for AFTER trigger delta tables.	  IIF (CAST (PlanAttributes.value as INT) & 2048 = 2048 , N'Enabled' , N'Disabled') as [ResyncQuery], --Indicates that the query was submitted by internal system stored procedures.		  IIF (CAST (PlanAttributes.value as INT) & 4096 = 4096 , N'Enabled' , N'Disabled') as [ARITH_ABORT],	  IIF (CAST (PlanAttributes.value as INT) & 8192 = 8192 , N'Enabled' , N'Disabled') as [NUMERIC_ROUNDABORT],	  IIF (CAST (PlanAttributes.value as INT) & 16384 = 16384 , N'Enabled' , N'Disabled') as [DATEFIRST],	  IIF (CAST (PlanAttributes.value as INT) & 32768 = 32768 , N'Enabled' , N'Disabled') as [DATEFORMAT],	  IIF (CAST (PlanAttributes.value as INT) & 65536 = 65536 , N'Enabled' , N'Disabled') as [LanguageID],	  IIF (CAST (PlanAttributes.value as INT) & 131072 = 131072 , N'Enabled' , N'Disabled') as [UPON], --Indicates that the database option PARAMETERIZATION was set to FORCED when the plan was compiled.	  IIF (CAST (PlanAttributes.value as INT) & 262144 = 262144 , N'Enabled' , N'Disabled') as [ROWCOUNT]FROM	sys.dm_exec_query_stats AS QueryStats	CROSS APPLY	sys.dm_exec_query_plan(QueryStats.plan_handle) as QueryPlan	CROSS APPLY 	sys.dm_exec_sql_text(QueryStats.plan_handle) as SqlText	CROSS APPLY	sys.dm_exec_plan_attributes (QueryStats.plan_handle) AS PlanAttributeswhere 	PlanAttributes.attribute = 'set_options'and SqlText.text like '%
%';

Now, this may not seem like it should be an issue, but this is affecting many .net applications out there. In management studio, ARITHABORT is defaulted on, but for .NET Applications, it is set to OFF. This is a legacy issue from the early days when Microsoft violated some of the ANSI standards. This setting Terminates a query when an overflow or divide by zero occurs during query execution. Microsoft even publishes a warning about this on the ARITHABORT setting stating:

现在,这似乎不应该成为问题,但这正在影响许多.net应用程序。 在Management Studio中,默认情况下为ARITHABORT,但对于.NET应用程序,它设置为OFF。 这是从Microsoft违反某些ANSI标准开始的早期遗留问题。 此设置在查询执行期间发生溢出或被零除时终止查询。 Microsoft甚至在ARITHABORT设置上发布有关此的警告,指出:

The default ARITHABORT setting for SQL Server Management Studio is ON. Client applications setting ARITHABORT to OFF can receive different query plans making it difficult to troubleshoot poorly performing queries. That is, the same query can execute fast in management studio but slow in the application. When troubleshooting queries with Management Studio always match the client ARITHABORT setting.

SQL Server Management Studio的默认ARITHABORT设置为ON。 将ARITHABORT设置为OFF的客户端应用程序可以接收不同的查询计划,从而很难对性能不佳的查询进行故障排除。 也就是说,同一查询可以在Management Studio中快速执行,但在应用程序中执行缓慢。 使用Management Studio进行查询故障排除时,请始终与客户端ARITHABORT设置匹配。

More information about the ARITHABORT option can be read . While Microsoft does state that this setting can be changed in the connection string for the application I was not able to find the syntax for adding the options. If you do have or know what the syntax is, please share this information below. However, the best option currently when troubleshooting SQL queries is to set your ARITHABORT OFF when troubleshooting queries to make sure you receive the same query plan.

可以在阅读有关ARITHABORT选项的更多信息。 尽管Microsoft确实声明可以在应用程序的连接字符串中更改此设置,但我找不到用于添加选项的语法。 如果您确实知道语法是什么,请在下面共享此信息。 但是,当前对SQL查询进行故障排除时最好的选择是在对查询进行故障排除时将ARITHABORT设置为OFF,以确保您收到相同的查询计划。

Another good way to get stuck spinning your wheels is to run a section of a stored procedure that requires a variable outside of a stored procedure. Most of us know that a troublesome stored procedure means that there is usually one bad section in the giant blob of code. This means that we end up removing and running sections one at a time. However, this can cause problems, when remove that section of code you will need to define that parameter. Most of us will default to either replacing the value directly in the SQL statement or declaring variables locally. This, of course, it allows SQL Server to make some assumptions about those values, allowing more accurate estimates and giving the query a better plan than what was inside the app.

使车轮卡住的另一个好方法是运行存储过程的一部分,该部分需要存储过程之外的变量。 我们大多数人都知道,麻烦的存储过程意味着在庞大的代码块中通常只有一个坏的部分。 这意味着我们最终一次只能删除和运行一节。 但是,这可能会导致问题,当删除该部分代码时,您将需要定义该参数。 我们大多数人将默认直接在SQL语句中替换值或在本地声明变量。 当然,这允许SQL Server对这些值进行一些假设,从而提供比应用程序内部更准确的估计并为查询提供更好的计划。

The easiest work around to this is to either use SP_Executesql or simply create a dummy stored procedure with that section of code. These methods shown below, allow SQL Server to execute the query in a parameterized fashion and imitates the behavior of the stored procedure more accurately.

解决此问题的最简单方法是使用SP_Executesql或仅使用该代码段创建虚拟存储过程。 下面显示的这些方法允许SQL Server以参数化的方式执行查询,并更准确地模拟存储过程的行为。

EXEC sp_executesql N'Select firstname, lastname from person where id = @param1', N'@param1 bigint', 26598GOCREATE PROCEDURE #querytuning @param1 int AS   BEGIN   Select firstname, lastname from person where id = @param1   ENDGOEXEC #querytuning @param1 = 26598

To demo this, using the adventureworks2017 database, I wrote the below queries to compare local variables with a dummy stored procedure. During this test, the local variable query ran roughly 50% faster consistently.

为了演示这一点,我使用Adventureworks2017数据库编写了以下查询,以将本地变量与虚拟存储过程进行比较。 在此测试期间,本地变量查询的运行速度始终保持大约50%的速度。

CREATE PROCEDURE #querytuningSalesPerson @param1 int AS   BEGINSelect [SalesOrderNumber],[OrderDate],[Status]from [Sales].[SalesOrderHeader]where [TotalDue] >= @param1ENDdeclare @param1 intset @param1 = 5 Select [SalesOrderNumber],[OrderDate],[Status]from [Sales].[SalesOrderHeader]where [TotalDue] >= @param1 EXEC #querytuningSalesPerson @param1 = 5

Finally, as hinted at briefly in the start of this article there are just going to be sometimes the query you are trying to tune is going to perform slow due to blocking issues in the DB that are not occurring during the time you are trying to tune this query. This is always slightly frustrating as it is one of the “intermittent issues” managers often complain about when running their quarterly reports or gathering large amounts of data. The best thing to do in this scenario is to keep good data on what queries tend to be the slowest and what queries you are receiving alerts on. It is also important to gather metrics for benchmarking and gathering baselines of how your server is performing over time. Microsoft talks about what and suggests some of . However, at minimum you should be monitoring your processes on your SQL Server to gauge how often blocking is occurring. Many DBAs do this on the cheap by Logging SP_WhoisActive to a table, it is even documented how to configure this by viewing the around the procedure online.

最后,正如本文开头所简要指出的那样,有时由于您试图调优的查询中未发生的阻塞数据库问题,您试图调优的查询有时会执行得很慢。此查询。 这总是让人有些沮丧,因为它是经理在运行季度报告或收集大量数据时经常抱怨的“间歇性问题”之一。 在这种情况下,最好的办法是保留有关哪些查询往往最慢以及收到警报的查询的良好数据。 收集指标以进行基准测试并收集服务器随时间的运行情况的基准也很重要。 Microsoft讨论了哪些并建议一些 。 但是,至少您应该在SQL Server上监视进程,以评估阻塞发生的频率。 许多DBA通过将SP_WhoisActive记录到表中来廉价地完成此操作,甚至通过在线查看有关过程的来记录如何配置此操作。

While we have only gone through a few of the steps that can cause different query plans and performance issues between your application and your management studio, I hope these topics help you with your performance tuning ventures as much as they did me.

尽管我们仅执行了一些步骤,这些步骤可能会导致您的应用程序和管理工作室之间出现不同的查询计划和性能问题,但我希望这些主题对您的性能调优活动能像我一样为您提供帮助。

翻译自:

ssms应用程序错误

转载地址:http://qwnwd.baihongyu.com/

你可能感兴趣的文章
kettle java交互_通过Java调取Kettle的结果集
查看>>
mysql 导致iis 假死_解决IIS无响应假死状态
查看>>
mysql数据库读取快照隔离_CookBook/1-MySQL数据库读写锁示例详解、事务隔离级别示例详解.md at master · cuiko/CookBook · GitHub...
查看>>
skinme java 路径错误_java 错误 classes路径配置错误
查看>>
python安装tensorflow gpu_[tensorflow] tensorflow-cpu/gpu 安装过程
查看>>
java二维数组矩阵_获取从二维数组矩阵的行和列在Java中
查看>>
scala mysql连接池_Scala 操作Redis使用连接池工具类RedisUtil
查看>>
css背景图片高斯模糊_CSS3 filter(滤镜) 制作图片高斯模糊无需JS
查看>>
matlab综合实验题库,数学实验matlab题库答案
查看>>
oracle wri$_adv_objects突增,SYSTEM Tablespace — oracle-tech
查看>>
python抓取oracle数据,python爬虫,抓取oracle-base上的一些常用脚本
查看>>
oracle分页用子查询,[亲测]Oracle查询--子查询,分页查询(二)
查看>>
oracle动态语句怎么传参数值,DATAX动态参数数据传递
查看>>
php怎么设置文本区域,PHP txt下载不写文本区域内容
查看>>
linux各个目录名称,描述Linux发行版的系统目录名称命名规则以及用途
查看>>
linux 脚本里切换用户密码,shell,切换用户,执行指定,脚本
查看>>
linux配置无密码登陆,Linux下配置ssh无密码登录
查看>>
linux视频对讲qt方案,QT下视频通话的实现
查看>>
顺序串c语言,数据结构c语言实现定长顺序串
查看>>
linux 安装qq2014,Ubuntu14.04安装wine QQ
查看>>