为什么SQL统计信息和分析器之间的执行时间不同?

时间:2017-06-20 13:33:43

标签: c# sql postman sql-execution-plan

我正在使用SQL Server Management Studio 2014.我的查询花费的时间超过了我想要返回的时间。我在用邮递员测试我的API时首先注意到了这个问题。请求从视图中选择数据并返回到客户端。

当我通过邮递员发送请求时,运行查询器的响应时间为2168毫秒。据我所知,在SQL 2014中,'持续时间'探查器窗口中的列以毫秒显示。

当我复制从分析器执行的语句并直接在SQL中使用' SET STATISTICS TIME ON'我的经过时间是342毫秒。

我觉得奇怪的是,执行同一个查询所花费的时间有多长。唯一的区别是第一个请求是直接从一个新的查询窗口在SQL服务器上运行的,其中粘贴了“exec sp_executesql”'言。

响应时间为2168的探查器的结果更符合我通过邮递员调用API的经验。

为什么通过postman服务执行查询所需的时间比在新查询窗口中执行时要长得多?在两个实例中执行的SQL都是相同的。

如何进一步排查故障并最终解决此问题?我相信这个查询应该在1秒内返回,就像在查询编辑器窗口中直接执行时一样。如前所述,我从分析器中复制了语句,以便我可以比较执行,并在执行时间方面得到两个不同的结果。

修改

在SSMS中查看“应用程序中的速度慢,SSMS快速”

我要看看,谢谢你的资源。我并不赞成它的苹果对苹果,但即使我罢工,我也一定会学到一些东西。我考虑过参数嗅探,但我已经在使用EXEC sp_executesql了。

查询返回了多少数据?

查询返回2,513行数据。据邮递员称,响应大小为2.84 MB。

您能告诉我们正在执行的查询吗? 当然,这是正在执行的查询:

exec sp_executesql N'SELECT  [PortalId], [UserId], [ItemId], [ItemTypeId], [Timezone], [Type], [FirstName], [LastName], [Name], [Description], [Price], [Hours], [IsShipped], [Status], [CourseUrl], [Progress], [CertificateUrl], [IsLaunched], [CompletionType], [Score], [TimeSpentSeconds], [FirstLaunchDateUtc], [LastActivityDateUtc], [EnrollmentDateUtc], [ExpirationDateUtc], [CompletedDateUtc], [Id], [CreatedOnUtc], [ModifiedOnUtc], [DeletedOnUtc], [CreatedBy], [ModifiedBy], [DeletedBy] FROM api.EnrollmentsDataView WHERE  ( [DeletedOnUtc]  IS NULL    AND   [PortalId] = @portalid0 ) ',N'@deletedonutc0 nvarchar(4000),@portalid0 bigint',@deletedonutc0=NULL,@portalid0=1

我从一个我已创建的视图中选择将多个表连接在一起。预计后续问题,以下是视图的代码:

SELECT Enrollments.[Id]
      ,Enrollments.[PortalId]
      ,Enrollments.[UserId]
      ,Enrollments.[ItemId]
      ,Items.ItemTypeId
      ,Timezones.Code as Timezone
      ,ItemTypes.Name as [Type]
      ,HlUsers.FirstName
      ,HlUsers.LastName
      ,Items.Name 
      ,Items.[Description]
      ,Items.Price
      ,Items.[Hours]
      ,Items.IsShipped    
      ,StatusTypes.Name as [Status]
      ,Enrollments.[CourseUrl]
      ,Enrollments.[Progress]
      ,Enrollments.[CertificateUrl]
      ,Enrollments.[IsLaunched]
      ,Enrollments.[CompletionType]
      ,Enrollments.[Score]
      ,Enrollments.[TimeSpentSeconds]
      ,Enrollments.[FirstLaunchDateUtc]
      ,Enrollments.[LastActivityDateUtc]
      ,Enrollments.[EnrollmentDateUtc]
      ,Enrollments.[ExpirationDateUtc]
      ,Enrollments.[CompletedDateUtc]
      ,Enrollments.[CreatedOnUtc]
      ,Enrollments.[CreatedBy]
      ,Enrollments.[ModifiedOnUtc]
      ,Enrollments.[ModifiedBy]
      ,Enrollments.[DeletedOnUtc]
      ,Enrollments.[DeletedBy]
  FROM Enrollments
  INNER JOIN Items
  ON Enrollments.ItemId = Items.Id
  INNER JOIN HlUsers
  ON HlUsers.Id = Enrollments.UserId
  INNER JOIN HlPortals
  ON HlPortals.Id = Enrollments.PortalId
  INNER JOIN StatusTypes
  ON StatusTypes.Id = Enrollments.StatusTypeId
  INNER JOIN ItemTypes 
  ON ItemTypes.Id = Items.ItemTypeId
  LEFT JOIN Timezones
  ON Timezones.Id = COALESCE(Enrollments.TimezoneId, HlUsers.TimezoneId, HLPortals.DefaultTimezoneId)

我正在运行视图并指定我只想要PortalId = 1和DeletedOnUtc IS NULL的结果。

您可以运行SQL事件探查器,并查看SQL Server处理您的请求所需的时间(通过api调用发出)。 sp_execute_sql vs只执行该语句是两种不同的野兽

感谢您的建议。我在运行探查器的SQL中运行查询。此次分析器的持续时间为493毫秒。这符合我的期望,但是没有解决为什么在通过配置文件测量并通过PostMan / .Net执行时查询运行时间长得多的问题。

至于如何优化即席查询语句 - 这是一个非常广泛的主题;你可以学习基础知识 - 比如这里的pluralsight.com/courses/...并提出后续问题:)

我当然可以在sql优化上使用一些刷新但我在这方面也不是一个完整的新手。我完全不知道为什么查询执行的持续时间会有这么大的差异,具体取决于它是如何被触发的。当直接执行时,性能很好所以遵循执行计划并且做出改变似乎不值得,直到我能够更好地理解这里发生的事情。也就是说,当我有时间的时候,我肯定会回顾这门课程。谢谢你的建议!

编辑#2

以下是从分析器中查看的通过SQL和PostMan运行的代码:

SQL:CPU:94读取:5537持续时间:384(匹配SQL中的持续时间)

SET STATISTICS TIME ON;

exec sp_executesql N'SELECT  [PortalId], [UserId], [ItemId], [ItemTypeId], [Timezone], [Type], [FirstName], [LastName], [Name], [Description], [Price], [Hours], [IsShipped], [Status], [CourseUrl], [Progress], [CertificateUrl], [IsLaunched], [CompletionType], [Score], [TimeSpentSeconds], [FirstLaunchDateUtc], [LastActivityDateUtc], [EnrollmentDateUtc], [ExpirationDateUtc], [CompletedDateUtc], [Id], [CreatedOnUtc], [ModifiedOnUtc], [DeletedOnUtc], [CreatedBy], [ModifiedBy], [DeletedBy] FROM api.EnrollmentsDataView WHERE  ( [DeletedOnUtc]  IS NULL    AND   [PortalId] = @portalid0 ) ',N'@deletedonutc0 nvarchar(4000),@portalid0 bigint',@deletedonutc0=NULL,@portalid0=1

SET STATISTICS TIME OFF;

邮递员:CPU:47阅读次数:5581持续时间:3403(匹配SQL中的持续时间)

exec sp_executesql N'SELECT  [PortalId], [UserId], [ItemId], [ItemTypeId], [Timezone], [Type], [FirstName], [LastName], [Name], [Description], [Price], [Hours], [IsShipped], [Status], [CourseUrl], [Progress], [CertificateUrl], [IsLaunched], [CompletionType], [Score], [TimeSpentSeconds], [FirstLaunchDateUtc], [LastActivityDateUtc], [EnrollmentDateUtc], [ExpirationDateUtc], [CompletedDateUtc], [Id], [CreatedOnUtc], [ModifiedOnUtc], [DeletedOnUtc], [CreatedBy], [ModifiedBy], [DeletedBy] FROM api.EnrollmentsDataView WHERE  ( [DeletedOnUtc]  IS NULL    AND   [PortalId] = @portalid0 ) ',N'@deletedonutc0 nvarchar(4000),@portalid0 bigint',@deletedonutc0=NULL,@portalid0=1

编辑#3 我在分析器中打开了Showplan Text(Unencoded),并且从postman触发的查询和从sql触发的查询都具有相同的确切执行计划。

这里发生了什么?

0 个答案:

没有答案