রিমাস সহায়কভাবে উল্লেখ করেছে যে VARCHAR
কলামটির সর্বাধিক দৈর্ঘ্য আনুমানিক সারির আকারকে প্রভাবিত করে এবং তাই এসকিউএল সার্ভার সরবরাহ করে মেমরি মঞ্জুরি দেয়।
আমি তার উত্তরের "এই বিষয়গুলি থেকে ক্যাসকেড" অংশটি আরও প্রসারিত করার জন্য আরও কিছু গবেষণা করার চেষ্টা করেছি। আমার সম্পূর্ণ বা সংক্ষিপ্ত ব্যাখ্যা নেই, তবে আমি যা পেয়েছি তা এখানে।
প্রতিস্থাপন স্ক্রিপ্ট
আমি একটি সম্পূর্ণ স্ক্রিপ্ট তৈরি করেছি যা একটি নকল তথ্য সেট উত্পন্ন করে যার উপর ভিত্তি করে সূচকটি তৈরি করা VARCHAR(256)
সংস্করণটির জন্য আমার মেশিনে প্রায় 10x সময় নেয় । ব্যবহৃত তথ্য ঠিক একই, কিন্তু প্রথম টেবিল প্রকৃত সর্বোচ্চ লেন্থ ব্যবহার 18
, 75
, 9
, 15
, 123
, এবং 5
, সমস্ত কলামের সর্বোচ্চ দৈর্ঘ্য ব্যবহার করার সময় 256
দ্বিতীয় সারণিতে।
মূল টেবিল চাবি
এখানে আমরা দেখতে পাই যে মূল ক্যোয়ারীটি প্রায় 20 সেকেন্ডের মধ্যে শেষ হয় এবং লজিকাল ~1.5GB
রিডগুলি (195K পৃষ্ঠাগুলি, প্রতি পৃষ্ঠায় 8 কে) সারণির আকারের সমান ।
-- CPU time = 37674 ms, elapsed time = 19206 ms.
-- Table 'testVarchar'. Scan count 9, logical reads 194490, physical reads 0
CREATE CLUSTERED INDEX IX_testVarchar
ON dbo.testVarchar (s1, s2, s3, s4)
WITH (MAXDOP = 8) -- Same as my global MAXDOP, but just being explicit
GO
VARCHAR (256) সারণী কী করা হচ্ছে
জন্য VARCHAR(256)
টেবিল, আমরা দেখতে যে ব্যায়িত সময় নাটকীয়ভাবে বৃদ্ধি পেয়েছে।
মজার বিষয় হল, সিপিইউ সময় বা যৌক্তিক পাঠগুলিও বৃদ্ধি পায় না। এই টেবিলের সঠিক একই ডেটা রয়েছে তা প্রদত্ত বোঝা যায়, তবে কেন বিচ্ছিন্ন সময় এত ধীর হয় তা ব্যাখ্যা করে না।
-- CPU time = 33212 ms, elapsed time = 263134 ms.
-- Table 'testVarchar256'. Scan count 9, logical reads 194491
CREATE CLUSTERED INDEX IX_testVarchar256
ON dbo.testVarchar256 (s1, s2, s3, s4)
WITH (MAXDOP = 8) -- Same as my global MAXDOP, but just being explicit
GO
I / O এবং অপেক্ষার পরিসংখ্যান: আসল
আমরা যদি আরও কিছু বিশদ ক্যাপচার করি ( p_perfMon ব্যবহার করে , আমি যে পদ্ধতিটি লিখেছিলাম ), আমরা দেখতে পাব যে I / O এর বিশাল অংশটিLOG
ফাইলটিতে সঞ্চালিত হয় । আমরা প্রকৃত ROWS
(মূল ডেটা ফাইল) -এ তুলনামূলকভাবে I / O পরিমাণের তুলনামূলক পরিমাণ দেখতে পাই এবং প্রাথমিক অপেক্ষার প্রকারটি LATCH_EX
মেমরির পৃষ্ঠা বিরোধীকরণের ইঙ্গিত দেয়।
পল র্যান্ডাল অনুসারে , আমরা দেখতে পাচ্ছি যে আমার স্পিনিং ডিস্কটি "খারাপ" এবং "হতভম্বভাবে খারাপ" এর মাঝে রয়েছে :)
I / O এবং অপেক্ষার পরিসংখ্যান: VARCHAR (256)
জন্য VARCHAR(256)
সংস্করণ, ইনপুট / আউটপুট এবং অপেক্ষার পরিসংখ্যান সম্পূর্ণ ভিন্ন চেহারা! এখানে আমরা ডেটা ফাইল ( ROWS
) এর আই / ও-তে একটি বিশাল বৃদ্ধি দেখতে পেয়েছি এবং স্টলের সময়গুলি এখন পল র্যান্ডালকে কেবল "ওয়াও!" বলে দেয়।
এটি অবাক হওয়ার মতো নয় যে # 1 অপেক্ষার প্রকারটি এখন IO_COMPLETION
। তবে কেন এত বেশি আই / ও উত্পন্ন হয়?
আসল ক্যোয়ারী প্ল্যান: ভোচারার (256)
ক্যোয়ারী পরিকল্পনা থেকে, আমরা দেখতে পাচ্ছি যে Sort
অপারেটরের ক্যোরির VARCHAR(256)
সংস্করণে একটি পুনরাবৃত্ত স্পিল (5 স্তর গভীর!) রয়েছে । (মূল সংস্করণে কোনও ছড়িয়ে পড়ে না))
লাইভ ক্যোয়ারী অগ্রগতি: VARCHAR (256)
আমরা এসকিউএল 2014+ এ লাইভ ক্যোয়ারী অগ্রগতি দেখতে sys.dm_exec_query_profiles ব্যবহার করতে পারি । মূল সংস্করণে, সম্পূর্ণ Table Scan
এবং Sort
কোনও ছিটকে ছাড়াই প্রক্রিয়া করা হয় ( পুরো spill_page_count
অবধি 0
)।
ইন VARCHAR(256)
সংস্করণ, যাইহোক, আমরা দেখতে পারেন পৃষ্ঠা উপচে পড়ার দ্রুত জন্য জমা Sort
অপারেটর। ক্যোয়ারী শেষ হওয়ার ঠিক আগে ক্যোয়ারির অগ্রগতির একটি স্ন্যাপশট এখানে। এখানে তথ্য সমস্ত থ্রেড জুড়ে একত্রিত হয়।
আমি যদি প্রতিটি থ্রেড পৃথকভাবে খনন করি তবে আমি দেখতে পাচ্ছি যে 2 টি থ্রেড প্রায় 5 সেকেন্ডের মধ্যে (টেবিল স্ক্যানে 15 সেকেন্ড ব্যয় করার পরে, সামগ্রিকভাবে 20 সেকেন্ড) সারণি সম্পূর্ণ করে। যদি সমস্ত থ্রেড এই হারে অগ্রসর হয় VARCHAR(256)
তবে সূচীকরণটি মূল টেবিলের মতো প্রায় একই সময়ে সম্পন্ন হত।
তবে, বাকি 6 টি থ্রেড অনেক ধীর গতিতে অগ্রসর হয়। এটি মেমরির যেভাবে বরাদ্দ করা হয়েছে এবং যেভাবে থ্রেডগুলি আই / ও দ্বারা আটকানো হচ্ছে তা ডেটা স্পিল করার কারণে এটি হতে পারে। যদিও আমি নিশ্চিত জানি না।
আপনি কি করতে পারেন?
আপনি চেষ্টা করার বিবেচনা করতে পারেন এমন অনেকগুলি বিষয় রয়েছে:
- কোনও পূর্ববর্তী সংস্করণে ফিরে যেতে বিক্রেতার সাথে কাজ করুন। যদি এটি সম্ভব না হয় তবে যে বিক্রেতাকে আপনি এই পরিবর্তনে সন্তুষ্ট নন যাতে তারা ভবিষ্যতের প্রকাশে এটিকে ফিরিয়ে আনার বিষয়টি বিবেচনা করতে পারে।
- আপনার সূচক যুক্ত করার সময়, আপনার বর্তমান সার্ভার-স্তরীয় সেটিংয়ের চেয়ে কম সংখ্যাটি
OPTION (MAXDOP X)
কোথায় রয়েছে X
তা ব্যবহার করার বিষয়টি বিবেচনা করুন । আমি যখন OPTION (MAXDOP 2)
আমার মেশিনে এই নির্দিষ্ট ডেটা সেটটিতে ব্যবহার করেছি, তখন VARCHAR(256)
সংস্করণটি শেষ হয়েছে 25 seconds
(8 টি থ্রেডের সাথে 3-4 মিনিটের তুলনায়!)। এটি সম্ভব যে স্পিলিং আচরণটি উচ্চতর সমান্তরালতার দ্বারা তীব্র হয়।
- যদি অতিরিক্ত হার্ডওয়্যার বিনিয়োগের সম্ভাবনা থাকে তবে আপনার সিস্টেমে আই / ও (সম্ভবত বিড়ম্বনা) প্রোফাইল দিন এবং প্রসারণ দ্বারা আয়োজিত আই / ও এর দীর্ঘসূত্রতা হ্রাস করার জন্য এসএসডি ব্যবহার করার বিষয়টি বিবেচনা করুন।
আরও পড়া
পল হোয়াইটের এসকিউএল সার্ভারের ধরণের ইন্টার্নিয়ালগুলিতে একটি দুর্দান্ত ব্লগ পোস্ট রয়েছে যা আগ্রহী হতে পারে। এটি স্পিলিং, থ্রেড স্কিউ এবং সমান্তরাল ধরণের জন্য মেমরির বরাদ্দ সম্পর্কে কিছুটা কথা বলে।