簡體   English   中英

SQL Server Express (localdb) 等待操作超時——查詢隨機超時?

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

我有一個簡單的SELECT查詢,它返回相對較大的數據集(11k 行),並且在我的應用程序運行時隨機超時。 這發生在我自己的開發筆記本電腦上,使用 localdb。 當它工作時,它幾乎立即返回數據,其他時候 - Microsoft.Data.SqlClient.SqlException: The wait operation timed out. . 當它失敗時,使用 SSMS 也感覺緩慢,但它總是完成查詢。

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

執行計划在這里。

我安裝了 Blitz 並運行sp_BlitzFirst來給我一些想法,但我不確定要查找什么以及如何解決問題。 請幫忙。

@@版本:

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:

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.

看來你的內存有問題。 您應該檢查您的狀態:

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

你不想等待。 同樣,你應該運行

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);

您在這里想要的是Available physical memory is high 如果沒有,則說明您的記憶力有問題。 那么問題是您是否有相互競爭的流程。

你可以嘗試一些事情

  • 查詢計划對表進行了兩次完整的聚集索引掃描。 鑒於您可能需要至少閱讀一遍(以獲取 Open 問題),您最好使用單個 SELECT 而不是 UNION。
    • 如果您可以使用索引進行查找並避免全表/聚集索引掃描,則 UNION 方法非常有效。 如果您沒有它可以使用的索引,那么您也可以限制讀取數據所需的次數。
  • order-by 會占用內存(排序會占用大量 CPU 和內存)。 是否可以通過 ID 而不是 DateOpened 進行排序?
  • 根據哪些狀態可用以及每個狀態有多少行,您可以在 [cm].[IssuesTbl].[Status] 上放置一個非聚集索引

這是我建議的代碼。 我更改了以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