Sql-Server

為什麼本屆會議特別暫停?請看詳情

  • May 13, 2020

我對會話暫停狀態的理解:

當查詢請求訪問目前不可用的資源時,查詢將被掛起。這可以是邏輯資源(如鎖定行)或物理資源(如記憶體數據頁)。一旦資源可用,查詢就會再次開始執行。

但是接下來的會議呢?

有問題的會話是下圖中的number 65, in yellow

我如何檢查該過程是否真的在做某事?

我知道網上有很多關於這個的問題,但是當它發生在我身上時我仍然無法弄清楚。

我的一個使用者正在執行以下一組更新:

       --------------------------------------------------------------
       -- need to add an update using the SUBS table
       --------------------------------------------------------------

/*      update dbo.FR_20150817 set
            title = s.title
           ,first_name = s.fname
           ,last_name = s.lname
       --  ,subscribe_date = s.subscribe_date
           ,newsletters = '1' -- s.newsletters
           ,style_notes = '1' -- s.style_notes
           ,sale_notifications = '1' -- s.sale_notifications
           ,all_my_offers = '1' -- s.all_my_offers
           ,ratings_and_reviews_invites = '1' -- s.ratings_and_reviews_invites
       from crm_staging.dbo.subs_20131009 s
       where 1 = 1
           and dbo.FR_20150817.email_address = s.email;
*/          

       insert into dbo.FR_20150817(
            email_address
           ,title
           ,first_name
           ,last_name
       --  ,subscribe_date
           ,newsletters
           ,style_notes
           ,sale_notifications
           ,all_my_offers
           ,ratings_and_reviews_invites
       )
       select s.email as 'email_address'
           ,case when len(s.title) = 1 then '' else isnull(s.title,'') end as 'title'
           ,case when len(s.fname) = 1 then '' else isnull(s.fname,'') end as 'first_name'
           ,case when len(s.lname) = 1 then '' else isnull(s.lname,'') end as 'last_name'
       --  ,s.sunscribe_date as 'subscribe_date'
           ,case when dbo.udf_check_empty(newsletters) = 1 then '0' else '1' end as 'newsletters'
           ,case when dbo.udf_check_empty(style_notes) = 1 then '0' else '1' end as 'style_notes'
           ,case when dbo.udf_check_empty(sale_notifications) = 1 then '0' else '1' end as 'sale_notifications'
           ,case when dbo.udf_check_empty(all_my_offers) = 1 then '0' else '1' end as 'all_my_offers'
           ,case when dbo.udf_check_empty(ratings_and_reviews_invites) = 1 then '0' else '1' end as 'ratings_and_reviews_invites'
       from crm_staging.dbo.subs_20131009 s
       where 1 = 1
           and s.aid = 2087301848
           and dbo.udf_reg_exp_match(isnull(s.email,''),N'^[a-zA-ZÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüŸ¡¿çÇŒœßØøÅåÆæÞþÐð0-9._%+-]+@[a-zA-ZÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüŸ¡¿çÇŒœßØøÅåÆæÞþÐð0-9.-]+\.[a-zA-ZÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüŸ¡¿çÇŒœßØøÅåÆæÞþÐð]{2,4}$') = 1
           and not exists (
               select d.email_address
               from dbo.FR_20150817 d
               where 1 = 1
                   and d.email_address = s.email
           )
           and not exists (
               select c.stremail
               from crm_staging.dbo.[01customers] c
               where 1 = 1
                   and c.stremail = s.email
           );


       update dbo.FR_20150817 set
            title = d.title
           ,first_name = d.fname
           ,last_name = d.lname
           ,newsletters = replace(replace(d.newsletters,'Y','1'),'N','0')
           ,style_notes = replace(replace(d.style_notes,'Y','1'),'N','0')
           ,sale_notifications = replace(replace(d.sale_notifications,'Y','1'),'N','0')
           ,all_my_offers = replace(replace(d.all_my_offers,'Y','1'),'N','0')
           ,ratings_and_reviews_invites = replace(replace(d.ratings_and_reviews_invites,'Y','1'),'N','0')
       from crm_staging.dbo.demo_20131009 d
       where 1 = 1
           and dbo.FR_20150817.email_address = d.email;

       update dbo.FR_20150817 set
            newsletters = 0
           ,style_notes = 0
           ,sale_notifications = 0
           ,all_my_offers = 0
           ,ratings_and_reviews_invites = 0
       from crm_staging.dbo.data_20131009_50 d
       where 1 = 1
           and dbo.FR_20150817.email_address = d.uid;

       update dbo.FR_20150817 set
            title = d.title
           ,first_name = d.fname
           ,last_name = d.lname
           ,newsletters = 0
           ,style_notes = 0
           ,sale_notifications = 0
           ,all_my_offers = 0
           ,ratings_and_reviews_invites = 0
       from crm_staging.dbo.unsubs_20131009 d
       where 1 = 1
           and dbo.FR_20150817.email_address = d.email;

使用可以在此處下載的 sp_whoisactive,我得到以下圖片:

在此處輸入圖像描述

讓我補充一點:

1)日誌文件有足夠的空間

2)磁碟有足夠的空間

3)沒有鎖和塊

  1. Tempdb 是一個變數 - 是的

5)理論上我有足夠的記憶體來進行所有這些更新

6)CPU應該沒問題 - 所以我相信

評估目前的等待統計資訊- 我沒有監控它們,只是在此處添加以獲取資訊

這是我用來收集它們的查詢:

select * 
from sys.dm_os_wait_stats
WHERE [wait_type] NOT IN (
       N'CLR_SEMAPHORE',    N'LAZYWRITER_SLEEP',
       N'RESOURCE_QUEUE',   N'SQLTRACE_BUFFER_FLUSH',
       N'SLEEP_TASK',       N'SLEEP_SYSTEMTASK',
       N'WAITFOR',          N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
       N'CHECKPOINT_QUEUE', N'REQUEST_FOR_DEADLOCK_SEARCH',
       N'XE_TIMER_EVENT',   N'XE_DISPATCHER_JOIN',
       N'LOGMGR_QUEUE',     N'FT_IFTS_SCHEDULER_IDLE_WAIT',
       N'BROKER_TASK_STOP', N'CLR_MANUAL_EVENT',
       N'CLR_AUTO_EVENT',   N'DISPATCHER_QUEUE_SEMAPHORE',
       N'TRACEWRITE',       N'XE_DISPATCHER_WAIT',
       N'BROKER_TO_FLUSH',  N'BROKER_EVENTHANDLER',
       N'FT_IFTSHC_MUTEX',  N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
       N'DIRTY_PAGE_POLL',  N'SP_SERVER_DIAGNOSTICS_SLEEP')
order by wait_time_ms desc;

在此處輸入圖像描述

我如何檢查該過程是否真的在做某事?

對於會話 65,程序被掛起,因為它正在等待程序完成。該等待資訊本身在此處突出顯示為 PAGEIOLATCH_SH..

這意味著來自MSDN

當任務正在等待不在 I/O 請求中的緩衝區的閂鎖時發生。鎖存請求處於共享模式。

這些等待通常與磁碟 I/O 瓶頸有關,儘管問題的根本原因可能是(通常是)性能不佳的查詢消耗了伺服器中過多的記憶體。PAGEIOLATCH_* 等待與從數據庫文件讀取或寫入數據的延遲特別相關。

您需要分析的第一件事是這種等待的頻率。將此與您的基線數據進行比較,看看它是否真的有問題。

可能它只出現了幾分之一秒,然後就消失了。萬一您說它沒有阻塞,對您來說應該不是那麼大的問題。但這又取決於您如何為數據設置基線。

參考這篇非常有用的文章Knee-Jerk Wait Statistics : PAGEIOLATCH_SH

以下是一些可能的根本原因(並非詳盡列表):

  • SQL Server 上的外部 Windows 記憶體壓力導致記憶體管理器減小緩衝池大小
  • 計劃記憶體膨脹導致從緩衝池借用額外記憶體
  • 執行表/聚集索引掃描(而不是索引查找)的查詢計劃,因為:

1. 工作量增加 2. 參數嗅探 3. 問題 已刪除或更改的必需非聚集索引 4. 隱式轉換

引用自:https://dba.stackexchange.com/questions/111269