দ্বিতীয় INSERT
বিবৃতিটি প্রথমটির চেয়ে 5x ডলার কম কেন ?
উত্পন্ন লগ ডেটার পরিমাণ থেকে, আমি মনে করি যে দ্বিতীয়টি ন্যূনতম লগিংয়ের জন্য যোগ্য নয়। তবে ডেটা লোডিং পারফরম্যান্স গাইডে থাকা ডকুমেন্টেশনগুলি নির্দেশ করে যে উভয় সন্নিবেশকে ন্যূনতমভাবে লগ করতে সক্ষম হওয়া উচিত। সুতরাং যদি ন্যূনতম লগিং মূল পারফরম্যান্সের পার্থক্য হয় তবে দ্বিতীয় কোয়েরি কেন ন্যূনতম লগিংয়ের জন্য যোগ্যতা অর্জন করে না? পরিস্থিতি উন্নয়নে কী করা যায়?
প্রশ্ন # 1: INSERT ব্যবহার করে 5 এমএম সারি সন্নিবেশ করা হচ্ছে ... (ট্যাবলক) সহ
নিম্নলিখিত কোয়েরিটি বিবেচনা করুন, যা 5 এমএম সারিগুলিকে একটি গাদা হিসাবে সন্নিবেশ করায়। এই ক্যোয়ারী বাস্তবায়িত হয় 1 second
এবং 64MB
লেনদেন লগ ডেটা দ্বারা রিপোর্ট হিসাবে উত্পন্ন sys.dm_tran_database_transactions
।
CREATE TABLE dbo.minimalLoggingTest (n INT NOT NULL)
GO
INSERT INTO dbo.minimalLoggingTest WITH (TABLOCK) (n)
SELECT n
-- Any table/view/sub-query that correctly estimates that it will generate 5MM rows
FROM dbo.fiveMillionNumbers
-- Provides greater consistency on my laptop, where other processes are running
OPTION (MAXDOP 1)
GO
ক্যোয়ারী # 2: একই ডেটা সন্নিবেশ করা হচ্ছে, তবে এসকিউএল সারিগুলির # টিকে হ্রাস করে
এখন এই খুব অনুরূপ ক্যোয়ারী বিবেচনা করুন, যা ঠিক একই ডেটাতে কাজ করে তবে একটি টেবিল থেকে আঁকতে দেখা যায় (বা SELECT
আমার সত্যিকারের উত্পাদনের ক্ষেত্রে অনেকগুলি সমন্বিত জটিল বিবৃতি) যেখানে কার্ডিনালিটির অনুমান খুব কম। এই ক্যোয়ারী কার্যকর করে 5.5 seconds
এবং 461MB
লেনদেনের লগ ডেটা তৈরি করে।
CREATE TABLE dbo.minimalLoggingTest (n INT NOT NULL)
GO
INSERT INTO dbo.minimalLoggingTest WITH (TABLOCK) (n)
SELECT n
-- Any table/view/sub-query that produces 5MM rows but SQL estimates just 1000 rows
FROM dbo.fiveMillionNumbersBadEstimate
-- Provides greater consistency on my laptop, where other processes are running
OPTION (MAXDOP 1)
GO
সম্পূর্ণ স্ক্রিপ্ট
পরীক্ষার ডেটা উত্পন্ন করার জন্য এবং এই জাতীয় দৃশ্যপটের কোনওটি সম্পাদন করতে সম্পূর্ণ স্ক্রিপ্টগুলির জন্য এই পাস্তবিনটি দেখুন । নোট করুন যে আপনাকে অবশ্যই একটি ডাটাবেস ব্যবহার করতে হবে যা SIMPLE
পুনরুদ্ধারের মডেলটিতে রয়েছে ।
ব্যবসায়ের প্রসঙ্গ
আমরা আধা ঘন ঘন লক্ষ লক্ষ সারির ডেটা ঘুরে বেড়াচ্ছি এবং কার্যকর করার সময় এবং ডিস্ক আই / ও লোড উভয় ক্ষেত্রেই এই অপারেশনগুলি যথাসম্ভব দক্ষ হওয়া জরুরি। আমরা প্রাথমিকভাবে এই ধারণাটির আওতায় ছিলাম যে একটি হিপ টেবিল তৈরি করা এবং INSERT...WITH (TABLOCK)
এটি করা ভাল উপায় ছিল তবে এখন আমরা কম আত্মবিশ্বাসী হয়েছি যে আমরা একটি বাস্তব উত্পাদন দৃশ্যে উপরে প্রদর্শিত পরিস্থিতিটি পর্যবেক্ষণ করেছি (আরও জটিল প্রশ্নগুলি না থাকলেও সরলীকৃত সংস্করণ এখানে)।
SELECT
বিবৃতি রয়েছে যার সাথে অনেকগুলি যোগ দেয় এবং এর ফলাফল নির্ধারণ করেINSERT
। এইগুলিতে চূড়ান্ত টেবিল সন্নিবেশকারী অপারেটরের (যা আমি খারাপUPDATE STATISTICS
কলের মাধ্যমে রেপ্রো স্ক্রিপ্টে সিমুলেটেড করেছি) এর জন্য দুর্বল কার্ডিনালিটির অনুমান উত্পাদন করিUPDATE STATISTICS
এবং সমস্যাটি সমাধানের জন্য একটি আদেশ জারি করার মতো এটি এতটা সহজ নয় । আমি সম্পূর্ণরূপে সম্মত হই যে ক্যোয়ারীটি সহজ করে তোলা যাতে কার্ডিনালিটি এসটিমেটরের পক্ষে এটি বোঝা আরও ভাল হয় যে কোনও ভাল পদ্ধতির হতে পারে তবে প্রদত্ত জটিল ব্যবসার যুক্তি বাস্তবায়ন করা কোনও ট্রিভাল নয়।