【问题标题】:Simple query is executed very slow to 100 rows简单查询执行非常慢到 100 行
【发布时间】:2016-10-06 09:43:49
【问题描述】:

我使用asp.net mvc,sql server。在我的存储库的类中查询。有时查询在 10 秒内执行,有时在 3 分钟内执行!!为什么?我使用了 SQL Server Profiler,但我真的不明白可能是什么原因以及如何找到它。

查询:

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[FirstAddressId] AS [FirstAddressId], 
    [Extent1].[SecondAddressId] AS [SecondAddressId], 
    [Extent1].[Distance] AS [Distance], 
    [Extent1].[JsonRoute] AS [JsonRoute]
    FROM [dbo].[AddressXAddressDistances] AS [Extent1]

【问题讨论】:

  • 当你使用SQLCMD或SSMS直接在数据库上执行查询时,需要多长时间?
  • 第一个猜测是阻塞,见blocking_session_id in sys.dm_exec_requests
  • @mason 在 SQL Server Management Studio 中用时不到 1 分钟
  • @JamesZ:我已经运行了我的查询和这个查询: SELECT session_id ,status ,blocking_session_id ,wait_type ,wait_time ,wait_resource ,transaction_id FROM sys.dm_exec_requests WHERE status = N'suspended'; GO 我在应用程序中收到错误“底层提供程序在打开时失败”。查询“sys.dm_exec_requests”执行 4 分钟。结果:53 暂停 0 PAGEIOLATCH_SH 48 6:1:414 1647388
  • 您的 SQL Server 实例是否在专用服务器上运行?

标签: asp.net sql-server asp.net-mvc repository-pattern


【解决方案1】:

检查您的查询计划。只需在 SqlServer Management Studio 中运行 SELECT 语句即可获得真正的查询计划。更多信息在这里:Query plan

如果它们相同,但调用之间的响应时间差异很大,则问题可能在于数据库级别的 lockc(或巨大的活动工作负载)。我的意思是不正确的事务隔离级别,或者同时运行的一些报告获取了过多的资源(或者“由于某些原因”生成锁以确保某些开发人员强制执行的某些数据一致性)。 许多因素都会影响性能(包括查询执行时可用的内存)。

您还可以运行一些查询来分析统计信息的质量(或使用 EXEC sp_updatestats 更新所有统计信息)或分析索引的碎片。我猜,但是我的锁和过时的统计信息或碎片整理的索引,会迫使 SqlServer 选择非常低效的查询计划。 关于活动锁的一些信息:Active locks on table

附加信息 1: 如果您是此数据库的唯一用户并且它在您的本地计算机上(您使用 SQLServer Express),那么与其他问题相比,锁定问题的可能性要小得多。尝试打开 SqlServer 的事件日志。它在引擎实例下左侧(树)的 SqlServer Management Studio 中可用:Management/Sql Server Logs/Current。你在那里看到任何不寻常的信息吗?也尝试查看系统日志(使用事件查看器应用程序)。如果出现硬件问题,您还应该看到一些信息。顺便说一句:你的表中有多少行?尝试在某些 Process Explorer 或 Performance Monitor 中查看磁盘的行为。如果磁盘队列长度太大,则可能是问题的主要根源(在这种情况下,请查看应用程序对磁盘的压力)...

更多关于锁的信息:

    SELECT 
      [spid] = session_Id
    , ecid
    , [blockedBy] = blocking_session_id 
    , [database] = DB_NAME(sp.dbid)
    , [user] = nt_username
    , [status] = er.status
    , [wait] = wait_type
    , [current stmt] = 
        SUBSTRING (
            qt.text, 
            er.statement_start_offset/2,
            (CASE 
                WHEN er.statement_end_offset = -1 THEN DATALENGTH(qt.text)  
                ELSE er.statement_end_offset 
            END - er.statement_start_offset)/2)
    ,[current batch] = qt.text
    , reads
    , logical_reads
    , cpu
    , [time elapsed (ms)] = DATEDIFF(mi, start_time,getdate())
    , program = program_name
    , hostname
    --, nt_domain
    , start_time
    , qt.objectid
FROM sys.dm_exec_requests er
INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle)as qt
WHERE session_Id > 50              -- Ignore system spids.
AND session_Id NOT IN (@@SPID)     -- Ignore this current statement.
ORDER BY 1, 2
GO

【讨论】:

  • 感谢您的回复。我检查了查询计划 - 它们是相同的。
  • 我已经使用“Lock:Timeout”运行分析器,并且我有许多其他数据库的超时行。我现在不使用这个数据库。为什么我有这个块: Lock:Timeout sa(LoginName)0(Duration) 8(SPID) 2016-06-07 07:55:47.710 2016-06-07 07:55:47.710 124278 PC\SQLEXPRESS MyDB(DBName) 1 (IsSystem) 0 - LOCK 3 - S 4 - SHARED_TRANSACTION_WORKSPACE 0 2 - 数据库锁定:超时 sa(LoginName)0(Duration) 35(SPID) 2016-06-07 07:55:47.710 2016-06-07 07:55: 47.710 124279 PC\SQLEXPRESS Lists (DBName) 1(IsSystem) 0 - LOCK 5 - X 5 - EXCLUSIVE_TRANSACTION_WORKSPACE 0 2 - DATABASE 正常吗?
  • 您使用的是哪个版本的 Express 版本?是 2016 年 12 月 14 日还是 2016 年的 RC?
  • 我使用 Microsoft SQL Server 2014 - 12.0.2000.8 (X64) Express Edition(64 位)。我的数据库有块: Lock:Timeout sa(LoginName) 8(SPID) 2016-06-07 09:38:27.510 2016-06-07 09:38:27.510 125315 1(IsSystem) PC\SQL(ServerName) 6(DBId) Couriers(DBNam‌​e) 0 - LOCK 3 - S 4 - SHARED_TRANSACTION_WORKSPACE 0 2 - DATABASE 如果我运行查询,我有另一个登录名。这个锁可能是问题的原因吗?为什么会出现这种锁定?
  • 关于事件日志。我发现了很多关于启动我拥有的所有数据库的日志。但我不运行它们。 2016 年 6 月 7 日 17:23:21,spid30s,启动数据库“MyDB”。 2016 年 6 月 7 日 17:23:21,spid30s,启动数据库“列表”。 2016 年 6 月 7 日 17:23:20,spid30s,启动数据库“任务列表”。 2016 年 6 月 7 日 17:23:20,spid30s,启动数据库“学生”。 2016 年 6 月 7 日 17:23:19,spid30s,启动数据库“邮递员”。 2016 年 6 月 7 日 16:53:13,spid29s,启动数据库“MyDB”。 2016 年 6 月 7 日 16:53:13,spid29s,启动数据库“列表”。
【解决方案2】:

在您为此浪费更多时间之前,您应该意识到,诸如查询在开发中花费的时间之类的东西本质上是没有意义的。在开发中,您在 IIS Express 中运行单线程 Web 服务器,这意味着您还运行了 VS,它位于大约 2-4 GB 的 RAM 上。与此同时,您正在运行一个 SQL Server 实例,它正在与系统争夺 RAM 和硬盘时间。您还没有给出系统的任何规格,但如果您碰巧使用的是消费级 5400 或 7200 RPM 盘片式驱动器而不是 SSD,那也会严重影响性能。然后,我们甚至还没有深入了解该系统上可能运行的其他内容。 Photoshop?外表?您最喜欢的 MP3 在后台解码的播放列表? Windows 在做什么?它可能正在下载/应用更新,为您的驱动器建立索引以进行搜索等。当您投入生产(或至少不应该)时,这些都不再适用。在生产环境中,您应该拥有一台配备 4-8 GB RAM 的专用服务器和一个 SSD 或企业级 15,000+ RPM 盘片驱动器,专门用于 SQL Server,这样它就可以以闪电般的速度输出查询结果。

总而言之,如果您想衡量您的应用程序的网站/查询性能,您需要将其部署到您将在生产中运行的复制品上。在那里,你可以彻底摆脱它并获得一些你可以实际做某事的真实数据。尝试在开发中分析您的应用完全是浪费时间。

【讨论】:

  • 我只使用 VS 和 Google Chrome 浏览器和一个标签。是的,我有 4 GB 的 RAM。但是我认为表中的 100 行对系统来说并不是那么困难
猜你喜欢
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多