我正在使用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触发的查询都具有相同的确切执行计划。
这里发生了什么?