এক্সএমএল পাঠকদের সাথে পরিকল্পনার অনুকূলকরণ


34

ডেডলক ইভেন্টগুলি ডিফল্ট বর্ধিত ইভেন্ট সেশন থেকে বের করতে এখান থেকে কোয়েরি সম্পাদন করা হচ্ছে

SELECT CAST (
    REPLACE (
        REPLACE (
            XEventData.XEvent.value ('(data/value)[1]', 'varchar(max)'),
            '<victim-list>', '<deadlock><victim-list>'),
        '<process-list>', '</victim-list><process-list>')
    AS XML) AS DeadlockGraph
FROM (SELECT CAST (target_data AS XML) AS TargetData
    FROM sys.dm_xe_session_targets st
    JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address
    WHERE [name] = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
    WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report';

আমার মেশিনে সম্পূর্ণ হতে 20 মিনিট সময় নেয়। পরিসংখ্যান রিপোর্ট করা হয়

Table 'Worktable'. Scan count 0, logical reads 68121, physical reads 0, read-ahead reads 0, 
         lob logical reads 25674576, lob physical reads 0, lob read-ahead reads 4332386.

 SQL Server Execution Times:
   CPU time = 1241269 ms,  elapsed time = 1244082 ms.

স্লো প্ল্যান এক্সএমএল

সমান্তরাল

আমি যদি WHEREক্লজটি সরিয়ে ফেলি তবে এটি ৩,782২ টি সারি ফেরার দ্বিতীয় সেকেন্ডের চেয়ে কম হয়ে যায়।

একইভাবে যদি আমি OPTION (MAXDOP 1)মূল ক্যোয়ারীতে যুক্ত করি যা এখনকার পরিসংখ্যানগুলির সাথে খুব দ্রুত গতিতে কম পড়া দেখায় showing

Table 'Worktable'. Scan count 0, logical reads 15, physical reads 0, read-ahead reads 0,
                lob logical reads 6767, lob physical reads 0, lob read-ahead reads 6076.

 SQL Server Execution Times:
   CPU time = 639 ms,  elapsed time = 693 ms.

দ্রুত পরিকল্পনা এক্সএমএল

ক্রমিক

আমার প্রশ্ন তাই

কি ঘটছে তা কেউ ব্যাখ্যা করতে পারেন? মূল পরিকল্পনাটি কেন এত বিপর্যয়কর এবং খারাপ সমস্যা এড়ানোর কোনও নির্ভরযোগ্য উপায় আছে?

সংযোজন:

আমি আরও জানতে পেরেছি যে INNER HASH JOINডিএমভির ফলাফলগুলি এত ছোট হওয়ায় ক্যোয়ারী পরিবর্তন করা কিছুটা হলেও উন্নতি করতে পারে (তবে এটি এখনও> 3 মিনিট সময় নেয়) আমি সন্দেহ করি যে যোগদানের ধরণটি নিজেই দায়বদ্ধ এবং অনুমান করি অন্য কিছু অবশ্যই পরিবর্তন হয়েছে। তার জন্য পরিসংখ্যান

Table 'Worktable'. Scan count 0, logical reads 30294, physical reads 0, read-ahead reads 0, 
          lob logical reads 10741863, lob physical reads 0, lob read-ahead reads 4361042.

 SQL Server Execution Times:
   CPU time = 200914 ms,  elapsed time = 203614 ms.

(এবং পরিকল্পনা)

প্রসারিত ইভেন্টগুলির রিং বাফারটি পূরণ করার পরে ( DATALENGTHএর মধ্যে XML4,880,045 বাইট ছিল এবং এতে 1,448 টি ইভেন্ট রয়েছে)) এবং MAXDOPইঙ্গিতটি সহ এবং ছাড়াই মূল ক্যোয়ারির একটি কাটা ডাউন সংস্করণ পরীক্ষা করে ।

SELECT COUNT(*)
FROM   (SELECT CAST (target_data AS XML) AS TargetData
        FROM   sys.dm_xe_session_targets st
               JOIN sys.dm_xe_sessions s
                 ON s.address = st.event_session_address
        WHERE  [name] = 'system_health') AS Data
       CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
WHERE  XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report'

SELECT*
FROM   sys.dm_db_task_space_usage
WHERE  session_id = @@SPID 

নিম্নলিখিত ফলাফল দিয়েছেন

+-------------------------------------+------+----------+
|                                     | Fast |   Slow   |
+-------------------------------------+------+----------+
| internal_objects_alloc_page_count   |  616 |  1761272 |
| internal_objects_dealloc_page_count |  616 |  1761272 |
| elapsed time (ms)                   |  428 |   398481 |
| lob logical reads                   | 8390 | 12784196 |
+-------------------------------------+------+----------+

টেম্পিডবি বরাদ্দগুলির মধ্যে একটি স্পষ্ট পার্থক্য রয়েছে যে 616পৃষ্ঠাগুলি দ্রুত দেখানো পৃষ্ঠাগুলি বরাদ্দ করা হয়েছিল এবং অবনমিত হয়েছিল। এক্সএমএলকে কোনও ভেরিয়েবলের মধ্যে রাখলে এটি একই পরিমাণ পৃষ্ঠাগুলি ব্যবহৃত হয়।

ধীর পরিকল্পনার জন্য এই পৃষ্ঠা বরাদ্দ গণনা কয়েক মিলিয়ন। dm_db_task_space_usageক্যোয়ারী চলমান রয়েছে এমন পোলিংয়ের মাধ্যমে দেখা যাচ্ছে যে এটি tempdbযে কোনও সময় একসাথে 1,800 এবং 3,000 পৃষ্ঠাগুলির বরাদ্দকৃত পৃষ্ঠাগুলি ক্রমাগত বরাদ্দ এবং অবনমিত করে চলেছে ।


আপনি WHEREক্লজটি এক্সকিউরি এক্সপ্রেশনে স্থানান্তর করতে পারেন ; যুক্তিবিজ্ঞান এটি দ্রুত যাওয়া অপসারণ করা হবে নেই: TargetData.nodes ('RingBufferTarget[1]/event[@name = "xml_deadlock_report"]')। এটি বলেছিল, আপনার উত্থাপিত প্রশ্নের উত্তর দেওয়ার জন্য আমি এক্সএমএল ইন্টার্নালগুলি ভালভাবে জানি না।
জন সেগেল

আপনার মার্টিনের জন্য @ এসকিউএলপুলবয়ে পেজিং ... তিনি এখানে আরও মন্তব্য করার পরামর্শ দিয়েছিলেন যেখানে তাঁর আরও দক্ষ পরামর্শ রয়েছে (সেগুলি উপরের কোডের উত্স নিবন্ধের ভিত্তিতে রয়েছে )।
অ্যারন বারট্রান্ড

উত্তর:


36

পারফরম্যান্স পার্থক্যের কারণ নির্বাহ ইঞ্জিনে স্কেলার এক্সপ্রেশনগুলি কীভাবে পরিচালনা করা হয় তার মধ্যে রয়েছে। এই ক্ষেত্রে, আগ্রহের প্রকাশটি হ'ল:

[Expr1000] = CONVERT(xml,DM_XE_SESSION_TARGETS.[target_data],0)

এই এক্সপ্রেশন লেবেল হয় একটি কম্পিউট স্কেলার অপারেটর দ্বারা নির্ধারিত হয়েছে (সিরিয়াল পরিকল্পনায় নোড 11, সমান্তরাল পরিকল্পনায় নোড 13)। কম্পিউট স্কেলার অপারেটরগুলি অন্য অপারেটরদের (এসকিউএল সার্ভার ২০০৫ এর পরবর্তী) থেকে পৃথক যে তারা যে সংজ্ঞাটি প্রকাশ করে সেগুলি দৃশ্যমান সম্পাদন পরিকল্পনায় প্রদর্শিত হবে এমন অবস্থানের প্রয়োজনীয়ভাবে মূল্যায়ন করা হয় না ; পরবর্তী অপারেটরের দ্বারা গণনার ফলাফল প্রয়োজন না হওয়া পর্যন্ত মূল্যায়ন স্থগিত করা যায়।

বর্তমান ক্যোয়ারিতে, target_data স্ট্রিংটি সাধারণত বড় হয়, স্ট্রিং থেকে XMLব্যয়বহুল রূপান্তর করে । ধীর পরিকল্পনায়, স্ট্রিং-এ XMLরূপান্তরটি প্রতিবারের পরে অপারেটরের সম্পাদিত হয় যার ফলাফলটি Expr1000পুনরায় প্রত্যাবর্তনের প্রয়োজন হয় ।

রিলেবন্ডিং একটি নেস্টেড লুপগুলির অভ্যন্তরীণ অংশে সংযুক্ত হয়ে যায় যখন একটি সম্পর্কিত প্যারামিটার (বাহ্যিক রেফারেন্স) পরিবর্তিত হয়। Expr1000এই নির্বাহ পরিকল্পনায় বেশিরভাগ নেস্টেড লুপগুলিতে যোগদানের জন্য একটি বহিরাগত রেফারেন্স। এক্সপ্রেশনটি বেশ কয়েকটি এক্সএমএল পাঠক, উভয় স্ট্রিম সমষ্টি এবং একটি স্টার্ট-আপ ফিল্টার দ্বারা একাধিকবার উল্লেখ করা হয়েছে। এর আকারের উপর নির্ভর করে XMLস্ট্রিংটি যে বারে রূপান্তরিত হয় তার সংখ্যা কয়েক মিলিয়নতে XMLসহজেই সংখ্যায়িত হতে পারে।

নীচের কল স্ট্যাকগুলি target_dataস্ট্রিংয়ে রূপান্তরিত হওয়ার উদাহরণগুলি দেখায় XML( ConvertStringToXMLForESযেখানে ES হয় এক্সপ্রেশন সার্ভিস ):

স্টার্ট-আপ ফিল্টার

ফিল্টার কল স্ট্যাক ফিল্টার

এক্সএমএল রিডার (টিভিএফ স্ট্রিম অভ্যন্তরীণভাবে)

টিভিএফ স্ট্রিম কল স্ট্যাক

সমষ্টি স্ট্রিম

সমষ্টি কল স্ট্যাক স্ট্রিম

স্ট্রিংকে রূপান্তর করা হচ্ছে XML প্রতিটি সময় এই অপারেটরগুলির মধ্যে যে কোনওটি পুনরায় প্রত্যাবর্তন করে নেস্টেড লুপস পরিকল্পনাগুলির সাথে পালন করা পারফরম্যান্স পার্থক্য ব্যাখ্যা করে। এটি সমান্তরালতা ব্যবহৃত হয় বা না তা নির্বিশেষে। এটি ঠিক তাই ঘটে যখন MAXDOP 1ইঙ্গিতটি নির্দিষ্ট করা হয় তখন অপ্টিমাইজার একটি হ্যাশ জোড় বেছে নেয় । যদি MAXDOP 1, LOOP JOINনির্দিষ্ট করা থাকে তবে ডিফল্ট সমান্তরাল পরিকল্পনার মতোই পারফরম্যান্সও দুর্বল (যেখানে অপ্টিমাইজার নেস্টেড লুপ পছন্দ করে)।

হ্যাশ যোগদানের সাথে কতটা পারফরম্যান্স বৃদ্ধি পায় তার উপর নির্ভর করে Expr1000অপারেটরের বিল্ড বা প্রোবের দিকে উপস্থিত রয়েছে কিনা । নিম্নলিখিত ক্যোয়ারী প্রোবের দিকে অভিব্যক্তিটি সনাক্ত করে:

SELECT CAST (
    REPLACE (
        REPLACE (
            XEventData.XEvent.value ('(data/value)[1]', 'varchar(max)'),
            '<victim-list>', '<deadlock><victim-list>'),
        '<process-list>', '</victim-list><process-list>')
    AS XML) AS DeadlockGraph
FROM (SELECT CAST (target_data AS XML) AS TargetData
    FROM sys.dm_xe_sessions s
    INNER HASH JOIN sys.dm_xe_session_targets st ON s.address = st.event_session_address
    WHERE [name] = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report';

আমি প্রশ্নের বর্ণিত সংস্করণ থেকে যোগদানের লিখিত আদেশটিকে উল্টো করে দিয়েছি, কারণ যোগদানের ইঙ্গিতগুলি ( INNER HASH JOINউপরে) পুরো ক্যোয়ারির জন্যও অর্ডারকে বাধ্য করে, ঠিক যেমন FORCE ORDERনির্দিষ্ট করা হয়েছিল। বিপরীতটি Expr1000তদন্তের পাশে উপস্থিত হওয়া নিশ্চিত করার জন্য প্রয়োজনীয় । কার্যকর করার পরিকল্পনার আকর্ষণীয় অংশটি হ'ল:

ইঙ্গিত ঘ

প্রোবের পাশ দিয়ে সংজ্ঞায়িত এক্সপ্রেশন দিয়ে, মানটি ক্যাশে করা হয়:

হ্যাশ ক্যাশে

Expr1000প্রথম অপারেটরের মান প্রয়োজন না হওয়া অবধি এখনও মূল্যায়ন স্থগিত করা হয় (উপরের স্ট্যাক ট্রেসটিতে স্টার্ট-আপ ফিল্টার) তবে গণিত মানটি ক্যাশ করা হয় ( CValHashCachedSwitch) এবং এক্সএমএল পাঠক এবং স্ট্রিম সমষ্টি দ্বারা পরবর্তী কলগুলির জন্য পুনরায় ব্যবহার করা হয়। নীচের স্ট্যাক ট্রেসটি এক্সএমএল রিডার দ্বারা ক্যাশেড মানটি পুনরায় ব্যবহার করার উদাহরণ দেখায়।

ক্যাশে পুনরায় ব্যবহার

যোগদানের ক্রমটি যখন বাধ্য করা Expr1000হয় তখন হ্যাশের যোগদানের দিকের সংজ্ঞাটি সংঘটিত হয়, পরিস্থিতি আলাদা হয়:

SELECT CAST (
    REPLACE (
        REPLACE (
            XEventData.XEvent.value ('(data/value)[1]', 'varchar(max)'),
            '<victim-list>', '<deadlock><victim-list>'),
        '<process-list>', '</victim-list><process-list>')
    AS XML) AS DeadlockGraph
FROM (SELECT CAST (target_data AS XML) AS TargetData
    FROM sys.dm_xe_session_targets st 
    INNER HASH JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address
    WHERE [name] = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report'

হাশ 2

ম্যাচের জন্য অনুসন্ধান শুরু করার আগে একটি হ্যাশ জোড় একটি সম্পূর্ণরূপে হ্যাড টেবিলটি তৈরি করতে তার বিল্ড ইনপুটটি পুরোপুরি পড়ে। ফলস্বরূপ, পরিকল্পনার তদন্ত দিক থেকে কেবল থ্রেড প্রতি এক কাজ করা উচিত নয়, আমাদের সমস্ত মান সংরক্ষণ করতে হবে । হ্যাশ যোগদানের tempdbজন্য XMLডেটা সঞ্চয় করতে একটি কাজের টেবিল ব্যবহার করা হয় এবং Expr1000পরবর্তী অপারেটরদের ফলাফলের প্রতিটি অ্যাক্সেসের জন্য এখানে ব্যয়বহুল ভ্রমণের প্রয়োজন হয় tempdb:

ধীরে অ্যাক্সেস

নিম্নলিখিতটি ধীর অ্যাক্সেসের পথের আরও বিশদ দেখায়:

ধীর বিশদ

যদি একত্রীকরণের জোড়কে বাধ্য করা হয় তবে ইনপুট সারিগুলি বাছাই করা হয় (একটি ব্লকিং অপারেশন, যেমন একটি হ্যাশ জোড়ায় বিল্ড ইনপুটের মতো) ফলস্বরূপ একই ব্যবস্থার ফলে যেখানে একটি মাধ্যমে ধীর অ্যাক্সেস হয় tempdb ডেটার আকারের কারণে বাছাই-অপ্টিমাইজড ওয়ার্কটেবলের প্রয়োজন required

যে পরিকল্পনাগুলি বৃহত ডেটা আইটেমগুলিতে হেরফের করে তা হরেক রকম কারণেই কার্যকর হতে পারে যা কার্যকর করার পরিকল্পনা থেকে আপাত নয়। হ্যাশ জয়েন (সঠিক ইনপুটটিতে অভিব্যক্তি সহ) ব্যবহার করা ভাল সমাধান নয়। এটি অননুমোদিত অভ্যন্তরীণ আচরণের উপর নির্ভর করে যে কোনও গ্যারান্টি ছাড়াই এটি পরের সপ্তাহে একইভাবে কাজ করবে, বা কিছুটা আলাদা কোয়েরিতে।

বার্তাটি হ'ল XMLম্যানিপুলেশন আজকে অনুকূলকরণের জন্য কৌশলপূর্ণ জিনিস হতে পারে। XMLউপরের দেখানোর চেয়ে শ্যাডিংয়ের আগে কোনও ভেরিয়েবল বা অস্থায়ী টেবিলটিতে লেখার বিষয়টি অনেক বেশি দৃ work় কাজ। এটি করার একটি উপায়:

DECLARE @data xml =
        CONVERT
        (
            xml,
            (
            SELECT TOP (1)
                dxst.target_data
            FROM sys.dm_xe_sessions AS dxs 
            JOIN sys.dm_xe_session_targets AS dxst ON
                dxst.event_session_address = dxs.[address]
            WHERE 
                dxs.name = N'system_health'
                AND dxst.target_name = N'ring_buffer'
            )
        )

SELECT XEventData.XEvent.value('(data/value)[1]', 'varchar(max)')
FROM @data.nodes ('./RingBufferTarget/event[@name eq "xml_deadlock_report"]') AS XEventData (XEvent)
WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report';

শেষ অবধি, আমি নীচের মন্তব্যগুলি থেকে মার্টিনের খুব দুর্দান্ত গ্রাফিক যুক্ত করতে চাই:

মার্টিনের গ্রাফিক


দুর্দান্ত ব্যাখ্যা, আপনাকে ধন্যবাদ। আমি আপনার নিবন্ধটি গণনা স্কেলারগুলিতে খুব পড়েছিলাম তবে এখানে দু'একটি রাখিনি।
মার্টিন স্মিথ

3
গতকাল প্রোফাইলিংয়ের সময় আমার প্রয়াসে অবশ্যই আমি কিছুটা গোলমাল করে ফেলেছি (সম্ভবত ধীর এবং দ্রুত চিহ্নগুলি মিশ্রিত হয়েছে!)। আমি আজ এটি আবার করেছি এবং অবশ্যই এটি ইতিমধ্যে আপনি ইতিমধ্যে যা বলেছেন তা দেখায়।
মার্টিন স্মিথ

2
হ্যাঁ স্ক্রিনশটটি ভিজ্যুয়াল স্টুডিও 2012 প্রোফাইলার থেকে কল ট্রি ভিউ প্রতিবেদন । আমি মনে করি যে পদ্ধতিগুলির নামগুলি আপনার আউটপুটে আরও পরিষ্কার দেখাচ্ছে যদিও রহস্যজনক স্ট্রিং যেমন @@IEAAXPEA_Kপ্রদর্শিত হচ্ছে না।
মার্টিন স্মিথ

10

মূলত এখানে পোস্ট করা আমার নিবন্ধের কোডটি হ'ল:

http://www.sqlservercentral.com/articles/deadlock/65658/

আপনি যদি মন্তব্যগুলি পড়ে থাকেন তবে আপনি বেশ কয়েকটি বিকল্প দেখতে পাবেন যার মধ্যে আপনি যে পারফরম্যান্স সমস্যার সম্মুখীন হচ্ছেন না সেগুলির মধ্যে একটি, সেই মূল ক্যোয়ারীর একটি পরিবর্তন ব্যবহার করে এবং অন্যটি এক্সএমএল প্রসেস করার আগে একটি ভেরিয়েবল ব্যবহার করে যা কার্যকর হয় which উত্তম. (পৃষ্ঠা 2 এ আমার মন্তব্য দেখুন) ডিএমভি থেকে এক্সএমএল প্রক্রিয়াটি ধীর হতে পারে, যেমন ডিএমএফ থেকে এক্সএমএলকে ফাইল টার্গেটের জন্য পার্স করা যায় যা প্রায়শই প্রথমে টেম্প টেবিলে ডেটা পড়ে এবং তারপরে প্রক্রিয়াজাতকরণের মাধ্যমে আরও ভালভাবে সম্পন্ন হয়। এসইকিউএল-এ এক্সএমএল। নেট বা এসকিউএলসিআর এর মতো জিনিসগুলির তুলনায় ধীর গতিতে।


1
ধন্যবাদ! কৌতুকটি করেছে। চলকবিহীন একটি 600 মিমি এবং 6341 রিডিং সহ এবং ভেরিয়েবল 303 msএবং সহ 3249 lob reads। ২০১২-তে আমারও and target_name='ring_buffer'সেই সংস্করণটি যুক্ত করতে হবে কারণ দেখে মনে হচ্ছে এখন দুটি লক্ষ্য রয়েছে। আমি এখনও 20 মিনিটের সংস্করণে এটি ঠিক কী করছে তার একটি মানসিক চিত্র পাওয়ার চেষ্টা করছি।
মার্টিন স্মিথ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.