简体   繁体   English

SQL Server Express (localdb) 等待操作超时——查询随机超时?

[英]SQL Server Express (localdb) The wait operation timed out - query timing out at random?

I have plain SELECT query that is returning relatively large dataset (11k rows) and it is randomly timing out when ran by my app.我有一个简单的SELECT查询,它返回相对较大的数据集(11k 行),并且在我的应用程序运行时随机超时。 This is happening on my own dev laptop using localdb.这发生在我自己的开发笔记本电脑上,使用 localdb。 When it works it returns data almost instantly, other times - Microsoft.Data.SqlClient.SqlException: The wait operation timed out.当它工作时,它几乎立即返回数据,其他时候 - Microsoft.Data.SqlClient.SqlException: The wait operation timed out. . . When it fails using SSMS also feels sluggish but it always finishes queries.当它失败时,使用 SSMS 也感觉缓慢,但它总是完成查询。

SQL is as follows SQL如下

(@CurrentUserId int)
-- First, select Draft issues created by current user
SELECT [I].[IssueId]
      ,[I].[IssueGuid]
      ,[I].[IssueNumber]
      ,[I].[DateCreated]
      ,[I].[DateOpened]
      ,[I].[DateLastModified]
      ,[I].[DateClosed]
      ,[I].[Title]
      ,[I].[Type]
      ,[I].[Status]
      ,[I].[CreatedByUserId]
      ,1 AS [OrderKey]
FROM [cm].[IssuesTbl] [I]
WHERE [I].[Status] = 0 AND [I].[CreatedByUserId] = @CurrentUserId

UNION ALL

-- Last, select Open issues
SELECT [I].[IssueId]
      ,[I].[IssueGuid]
      ,[I].[IssueNumber]
      ,[I].[DateCreated]
      ,[I].[DateOpened]
      ,[I].[DateLastModified]
      ,[I].[DateClosed]
      ,[I].[Title]
      ,[I].[Type]
      ,[I].[Status]
      ,[I].[CreatedByUserId]
      ,2 AS [OrderKey]
FROM [cm].[IssuesTbl] [I]
WHERE [I].[Status] = 1

ORDER BY [OrderKey] ASC, [I].[DateOpened] DESC, [I].[DateCreated] DESC

Execution plan is here.执行计划在这里。

I installed Blitz and ran sp_BlitzFirst to give me some idea but I'm not sure what to look for and how to fix the problem.我安装了 Blitz 并运行sp_BlitzFirst来给我一些想法,但我不确定要查找什么以及如何解决问题。 Please help.请帮忙。

@@version: @@版本:

Microsoft SQL Server 2016 (SP1) (KB3182545) - 13.0.4001.0 (X64)   Oct 28 2016 18:17:30   Copyright (c) Microsoft Corporation  Express Edition (64-bit) on Windows 10 Enterprise 6.3 <X64> (Build 17134: )

sp_BlitzFirst: sp_BlitzFirst:

10  Server Performance  Poison Wait Detected: RESOURCE_SEMAPHORE
For 4 seconds over the last 5 seconds, SQL Server was waiting on this particular bottleneck.

200 Wait Stats  RESOURCE_SEMAPHORE
For 4 seconds over the last 5 seconds, SQL Server was waiting on this particular bottleneck.

It seems you have memory issues.看来你的内存有问题。 You should run a check on your status:您应该检查您的状态:

SELECT 
  ((t1.requested_memory_kb)/1024.00) MemoryRequestedMB
  , CASE WHEN t1.grant_time IS NULL THEN 'Waiting' ELSE 'Granted' END AS RequestStatus
  , t1.timeout_sec SecondsToTerminate
FROM sys.dm_exec_query_memory_grants t1
  CROSS APPLY sys.dm_exec_sql_text(t1.sql_handle) t2

You do not want to have waiting.你不想等待。 Similarily, you should run同样,你应该运行

SELECT total_physical_memory_kb, available_physical_memory_kb, 
       total_page_file_kb, available_page_file_kb, 
       system_memory_state_desc
FROM sys.dm_os_sys_memory WITH (NOLOCK) OPTION (RECOMPILE);

What you want here is Available physical memory is high .您在这里想要的是Available physical memory is high If you do not, it means you have problems with memory.如果没有,则说明您的记忆力有问题。 The question then is whether you have competing processes.那么问题是您是否有相互竞争的流程。

A few things you may try你可以尝试一些事情

  • The query plan has two full clustered index scans on the table.查询计划对表进行了两次完整的聚集索引扫描。 Given that you'll probably need to read it all at least once (to get the Open issues), you may as well use a single SELECT instead of the UNION.鉴于您可能需要至少阅读一遍(以获取 Open 问题),您最好使用单个 SELECT 而不是 UNION。
    • The UNION approach works really well if you can use indexes to do seeks and avoid full table/clustered index scans.如果您可以使用索引进行查找并避免全表/聚集索引扫描,则 UNION 方法非常有效。 If you don't have indexes it can use, then you may as well limit the number of times you need to read the data.如果您没有它可以使用的索引,那么您也可以限制读取数据所需的次数。
  • The order-by eats memory (ordering takes a lot of CPU and memory). order-by 会占用内存(排序会占用大量 CPU 和内存)。 Is it possible to order by, say, ID rather than DateOpened?是否可以通过 ID 而不是 DateOpened 进行排序?
  • Depending on what statuses are available and how many rows of each status there are, you put a non-clustered index on [cm].[IssuesTbl].[Status]根据哪些状态可用以及每个状态有多少行,您可以在 [cm].[IssuesTbl].[Status] 上放置一个非聚集索引

Here's my suggested code.这是我建议的代码。 I changed the order by to start with Status because it will already be in order, but I haven't changed the second field to be ID - but do this if you can.我更改了以Status开头的顺序,因为它已经按顺序排列了,但我没有将第二个字段更改为 ID - 但如果可以,请执行此操作。

SELECT [I].[IssueId]
      ,[I].[IssueGuid]
      ,[I].[IssueNumber]
      ,[I].[DateCreated]
      ,[I].[DateOpened]
      ,[I].[DateLastModified]
      ,[I].[DateClosed]
      ,[I].[Title]
      ,[I].[Type]
      ,[I].[Status]
      ,[I].[CreatedByUserId]
      ,CASE WHEN [I].[Status]=1 THEN 2 ELSE 1 END AS [OrderKey]
FROM [cm].[IssuesTbl] [I]
WHERE ([I].[Status] = 1)
      OR ([I].[Status] = 0 AND [I].[CreatedByUserId] = @CurrentUserId)
ORDER BY [I].[Status] ASC, [I].[DateOpened] DESC, [I].[DateCreated] DESC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM