سؤال

انا اجري EXEC sp_who2 78 وأحصل على ما يلي نتائج:

results of sp_who2 for spid 78

كيف يمكنني معرفة سبب تعليق حالتها؟

هذه العملية ثقيلة INSERT بناء على استفسار باهظ الثمن.كبير SELECT الذي يحصل على البيانات من عدة جداول ويكتب حوالي 3-4 ملايين صف في جدول مختلف.

لا توجد أقفال / كتل.

ال waittype إنه مرتبط به CXPACKET.وهو ما أستطيع أن أفهمه لأن هناك 9 78 كما ترون في الصورة أدناه.

ما يهمني وما أود معرفته حقًا هو سبب الرقم 1 في SPID 78 موقوف.

أنا أفهم أنه عندما تكون حالة أ SPID تم تعليقه، فهذا يعني أن العملية تنتظر المورد وستستأنف عندما تحصل على المورد الخاص بها.

كيف يمكنني العثور على مزيد من التفاصيل حول هذا؟ما الموارد؟لماذا هو غير متوفر؟

أستخدم الكود أدناه كثيرًا، وأشكال مختلفة منه، ولكن هل هناك أي شيء آخر يمكنني فعله لمعرفة سبب ذلك SPID معلق؟

select * 
from sys.dm_exec_requests r
join sys.dm_os_tasks t on r.session_id = t.session_id
where r.session_id = 78

لقد استخدمت بالفعل sp_whoisactive.النتيجة التي أحصل عليها لهذا spid78 بالذات هي كما يلي:(مقسمة إلى 3 صور لتناسب الشاشة)

enter image description here

هل كانت مفيدة؟

المحلول

معلق:وهذا يعني أن الطلب غير نشط حاليًا لأنه ينتظر موردًا.يمكن أن يكون المورد عبارة عن إدخال/إخراج لقراءة صفحة ما، أو يمكن أن يكون WAITit عبارة عن اتصال على الشبكة، أو في انتظار القفل أو المزلاج.سيصبح نشطًا بمجرد اكتمال المهمة التي ينتظرها.على سبيل المثال، إذا قام الاستعلام بنشر طلب إدخال/إخراج لقراءة بيانات جدول كامل tblStudents، فسيتم تعليق هذه المهمة حتى اكتمال الإدخال/الإخراج.بمجرد اكتمال الإدخال/الإخراج (تتوفر بيانات الجدول tblStudents في الذاكرة)، سينتقل الاستعلام إلى قائمة الانتظار RUNNABLE.

لذا، إذا كان في حالة انتظار، فتحقق من عمود wait_type لفهم ما ينتظره واستكشاف الأخطاء وإصلاحها بناءً على وقت الانتظار.

لقد قمت بتطوير الإجراء التالي الذي يساعدني في ذلك، وهو يتضمن WAIT_TYPE.

use master
go

CREATE PROCEDURE [dbo].[sp_radhe] 

AS
BEGIN

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT es.session_id AS session_id
,COALESCE(es.original_login_name, '') AS login_name
,COALESCE(es.host_name,'') AS hostname
,COALESCE(es.last_request_end_time,es.last_request_start_time) AS last_batch
,es.status
,COALESCE(er.blocking_session_id,0) AS blocked_by
,COALESCE(er.wait_type,'MISCELLANEOUS') AS waittype
,COALESCE(er.wait_time,0) AS waittime
,COALESCE(er.last_wait_type,'MISCELLANEOUS') AS lastwaittype
,COALESCE(er.wait_resource,'') AS waitresource
,coalesce(db_name(er.database_id),'No Info') as dbid
,COALESCE(er.command,'AWAITING COMMAND') AS cmd
,sql_text=st.text
,transaction_isolation =
    CASE es.transaction_isolation_level
    WHEN 0 THEN 'Unspecified'
    WHEN 1 THEN 'Read Uncommitted'
    WHEN 2 THEN 'Read Committed'
    WHEN 3 THEN 'Repeatable'
    WHEN 4 THEN 'Serializable'
    WHEN 5 THEN 'Snapshot'
END
,COALESCE(es.cpu_time,0) 
    + COALESCE(er.cpu_time,0) AS cpu
,COALESCE(es.reads,0) 
    + COALESCE(es.writes,0) 
    + COALESCE(er.reads,0) 
    + COALESCE(er.writes,0) AS physical_io
,COALESCE(er.open_transaction_count,-1) AS open_tran
,COALESCE(es.program_name,'') AS program_name
,es.login_time
FROM sys.dm_exec_sessions es
    LEFT OUTER JOIN sys.dm_exec_connections ec ON es.session_id = ec.session_id
    LEFT OUTER JOIN sys.dm_exec_requests er ON es.session_id = er.session_id
    LEFT OUTER JOIN sys.server_principals sp ON es.security_id = sp.sid
    LEFT OUTER JOIN sys.dm_os_tasks ota ON es.session_id = ota.session_id
    LEFT OUTER JOIN sys.dm_os_threads oth ON ota.worker_address = oth.worker_address
    CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS st
where es.is_user_process = 1 
  and es.session_id <> @@spid
ORDER BY es.session_id

end 

هذا الاستعلام أدناه أيضاً يمكنك إظهار المعلومات الأساسية للمساعدة عند تعليق spid، وذلك بإظهار المورد الذي ينتظره spid.

SELECT  wt.session_id, 
    ot.task_state, 
    wt.wait_type, 
    wt.wait_duration_ms, 
    wt.blocking_session_id, 
    wt.resource_description, 
    es.[host_name], 
    es.[program_name] 
FROM  sys.dm_os_waiting_tasks  wt  
INNER  JOIN sys.dm_os_tasks ot ON ot.task_address = wt.waiting_task_address 
INNER JOIN sys.dm_exec_sessions es ON es.session_id = wt.session_id 
WHERE es.is_user_process =  1 

يرجى الاطلاع على الصورة أدناه كمثال:

enter image description here

نصائح أخرى

أستخدم sp_whoIsActive للنظر في هذا النوع من المعلومات لأنها أداة مجانية جاهزة تمنحك معلومات جيدة لاستكشاف أخطاء الاستعلامات البطيئة وإصلاحها:

كيفية استخدام sp_WhoIsActive للبحث عن استعلامات SQL Server البطيئة

باستخدام هذا، يمكنك الحصول على نص الاستعلام، والخطة التي يستخدمها، والمورد الذي ينتظره الاستعلام، وما الذي يمنعه، وما هي الأقفال التي يزيلها، وغير ذلك الكثير.

أسهل بكثير من محاولة التدحرج بنفسك.

يمكنك حلها بالطرق التالية:

  1. إصلاح مؤشر الكتلة.
  2. استخدم الجداول الزمنية للحصول على جزء من الجدول بأكمله والعمل معه.

لدي نفس المشكلة مع جدول يحتوي على 400.000.000 صف، واستخدم جداول زمنية للحصول على جزء منه ثم أستخدم عوامل التصفية والعناصر الداخلية لأن تغيير الفهرس لم يكن خيارًا.

بعض الأمثلة:

--
--this is need be cause DECLARE @TEMPORAL are not well for a lot of data.
CREATE TABLE #TEMPORAL
(
    ID BIGINT,
    ID2 BIGINT,
    DATA1 DECIMAL,
    DATA2 DECIMAL
);

WITH TABLE1 AS
(
    SELECT
        L.ID,
        L.ID2,
        L.DATA
    FROM LARGEDATA L
    WHERE L.ID = 1
), WITH TABLE2 AS
(
    SELECT
        L.ID,
        L.ID2,
        L.DATA
    FROM LARGEDATA L
    WHERE L.ID = 2
) INSERT INTO #TEMPORAL SELECT
    T1.ID,
    T2.ID,
    T1.DATA,
    T2.DATA
FROM TABLE1 T1
    INNER JOIN TABLE2 T2
        ON T2.ID2 = T2.ID2;
--
--this take a lot of resources proces and time and be come a status suspend, this why i need a temporal table.
SELECT
    *
FROM #TEMPORAL T
WHERE T.DATA1 < T.DATA2
--
--IMPORTANT DROP THE TABLE.
DROP TABLE #TEMPORAL
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top