আমার কাছে একটি কোয়েরি রয়েছে যা এসকিউএল সার্ভার ২০১২ সালে 800 মিলি সেকেন্ডে চলে এবং এসকিউএল সার্ভার 2014-এ প্রায় 170 সেকেন্ড সময় নেয় । আমি মনে করি যে আমি এটিকে Row Count Spool
অপারেটরের খারাপ কার্ডিনালিটির প্রাক্কলন হিসাবে সংকুচিত করেছি । আমি স্পুল অপারেটরদের সম্পর্কে কিছুটা পড়েছি (যেমন, এখানে এবং এখানে ), তবে এখনও কয়েকটি জিনিস বুঝতে সমস্যা হচ্ছে:
- এই কোয়েরিতে
Row Count Spool
অপারেটরের প্রয়োজন কেন ? আমি মনে করি না এটি সঠিকতার জন্য প্রয়োজনীয়, তাই এটি কোন নির্দিষ্ট অপ্টিমাইজেশন সরবরাহ করার চেষ্টা করছে? - এসকিউএল সার্ভার কেন অনুমান করে যে
Row Count Spool
অপারেটরে যোগ দেওয়া সমস্ত সারি সরিয়ে দেয়? - এটি কি এসকিউএল সার্ভার 2014 এ একটি বাগ? যদি তা হয় তবে আমি কানেক্টে ফাইল করব। তবে আমি প্রথমে আরও গভীর বোঝা চাই।
দ্রষ্টব্য: LEFT JOIN
এসকিউএল সার্ভার ২০১২ এবং এসকিউএল সার্ভার ২০১৪ উভয়ই গ্রহণযোগ্য কর্মক্ষমতা অর্জনের জন্য আমি কোয়েরিটিকে আবার লিখতে বা টেবিলগুলিতে সূচিগুলি যুক্ত করতে পারি So কীভাবে ক্যোয়ারীটি আলাদাভাবে বাক্য বলবেন।
ধীর ক্যোয়ারী
একটি সম্পূর্ণ পরীক্ষার স্ক্রিপ্টের জন্য এই পাস্তবিনটি দেখুন । এখানে আমি নির্দিষ্ট পরীক্ষার কোয়েরিটি দেখছি:
-- Prune any existing customers from the set of potential new customers
-- This query is much slower than expected in SQL Server 2014
SELECT *
FROM #potentialNewCustomers -- 10K rows
WHERE cust_nbr NOT IN (
SELECT cust_nbr
FROM #existingCustomers -- 1MM rows
)
এসকিউএল সার্ভার 2014: আনুমানিক ক্যোয়ারী পরিকল্পনা
এসকিউএল সার্ভার বিশ্বাস করে যে এটি Left Anti Semi Join
থেকে Row Count Spool
10,000 সারিগুলি 1 টি সারিতে ফিল্টার করবে। এই কারণে, এটি LOOP JOIN
পরবর্তী যোগদানের জন্য একটি নির্বাচন করে #existingCustomers
।
এসকিউএল সার্ভার 2014: আসল ক্যোয়ারী পরিকল্পনা
যেমনটি প্রত্যাশা করা হয়েছিল (এসকিউএল সার্ভার ছাড়াও সবার দ্বারা!), এর Row Count Spool
কোনও সারি সরানো হয়নি। সুতরাং যখন আমরা এসকিউএল সার্ভারটি একবার লুপ করার প্রত্যাশা করছিলাম তখন আমরা 10,000 বার লুপ করছি।
এসকিউএল সার্ভার ২০১২: আনুমানিক ক্যোয়ারী পরিকল্পনা
এসকিউএল সার্ভার ২০১২ ব্যবহার করার সময় (বা OPTION (QUERYTRACEON 9481)
এসকিউএল সার্ভার ২০১৪), Row Count Spool
সারিগুলির আনুমানিক # কমিয়ে দেয় না এবং একটি হ্যাশ জয়েন বেছে নেওয়া হয়, এর ফলে আরও উন্নততর পরিকল্পনার ফলস্বরূপ।
বাম জোট আবার লিখুন
রেফারেন্সের জন্য, এখানে এমন একটি উপায় রয়েছে যে সমস্ত এসকিউএল সার্ভার ২০১২, ২০১৪ এবং ২০১ 2016 সালে ভাল পারফরম্যান্স অর্জনের জন্য আমি আবারো কোয়েরিটি আবার লিখতে পারি, তবে, আমি এখনও উপরোক্ত প্রশ্নের সুনির্দিষ্ট আচরণে আগ্রহী এবং তা কিনা নতুন এসকিউএল সার্ভার 2014 কার্ডিনালিটি এসটিমেটরের একটি বাগ।
-- Re-writing with LEFT JOIN yields much better performance in 2012/2014/2016
SELECT n.*
FROM #potentialNewCustomers n
LEFT JOIN (SELECT 1 AS test, cust_nbr FROM #existingCustomers) c
ON c.cust_nbr = n.cust_nbr
WHERE c.test IS NULL