كيف تعرف سبب تعليق حالة spid؟ما هي الموارد التي ينتظرها spid؟
-
21-12-2019 - |
سؤال
انا اجري EXEC sp_who2 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 صور لتناسب الشاشة)
المحلول
معلق:وهذا يعني أن الطلب غير نشط حاليًا لأنه ينتظر موردًا.يمكن أن يكون المورد عبارة عن إدخال/إخراج لقراءة صفحة ما، أو يمكن أن يكون 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
يرجى الاطلاع على الصورة أدناه كمثال:
نصائح أخرى
أستخدم sp_whoIsActive للنظر في هذا النوع من المعلومات لأنها أداة مجانية جاهزة تمنحك معلومات جيدة لاستكشاف أخطاء الاستعلامات البطيئة وإصلاحها:
كيفية استخدام sp_WhoIsActive للبحث عن استعلامات SQL Server البطيئة
باستخدام هذا، يمكنك الحصول على نص الاستعلام، والخطة التي يستخدمها، والمورد الذي ينتظره الاستعلام، وما الذي يمنعه، وما هي الأقفال التي يزيلها، وغير ذلك الكثير.
أسهل بكثير من محاولة التدحرج بنفسك.
يمكنك حلها بالطرق التالية:
- إصلاح مؤشر الكتلة.
- استخدم الجداول الزمنية للحصول على جزء من الجدول بأكمله والعمل معه.
لدي نفس المشكلة مع جدول يحتوي على 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