কেন এই ক্যোয়ারী ইনডেক্স স্পুল ব্যবহার করে না?


23

অপ্টিমাইজারের আচরণটি আরও ভালভাবে বুঝতে এবং সূচি স্পলের চারপাশের সীমাগুলি বোঝার জন্য আমি এই প্রশ্নটি করছি। মনে করুন যে আমি এক থেকে 10000 পর্যন্ত পূর্ণসংখ্যা স্থাপন করেছি:

CREATE TABLE X_10000 (ID INT NOT NULL);
truncate table X_10000;

INSERT INTO X_10000 WITH (TABLOCK)
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

এবং একটি নেস্টেড লুপটি এর সাথে যোগ দিতে বাধ্য করুন MAXDOP 1:

SELECT *
FROM X_10000 a
INNER JOIN X_10000 b ON a.ID = b.ID
OPTION (LOOP JOIN, MAXDOP 1);

এটি এসকিউএল সার্ভারের দিকে নেওয়া একটি বরং বন্ধুত্বপূর্ণ ক্রিয়া। উভয় টেবিলের কোনও প্রাসঙ্গিক সূচী না থাকলে নেস্টেড লুপটি প্রায়শই ভাল যোগ হয় না। পরিকল্পনাটি এখানে:

খারাপ জিজ্ঞাসা

টেবিল স্পুল থেকে 100000000 সারি নিয়ে ক্যোয়ারীটি আমার মেশিনে 13 সেকেন্ড সময় নেয়। যাইহোক, কোয়েরিটি কেন ধীর হতে হবে তা আমি দেখছি না। ক্যোয়ারী অপ্টিমাইজারের সূচি স্পলের মাধ্যমে ফ্লাইতে সূচি তৈরির ক্ষমতা রয়েছে । এই ক্যোয়ারীটি মনে হচ্ছে এটি কোনও সূচক স্পুলের জন্য নিখুঁত প্রার্থী হবে।

নিম্নলিখিত ক্যোয়ারী প্রথমটির মতো একই ফলাফল দেয়, একটি সূচক স্পুল রয়েছে এবং এক সেকেন্ডেরও কম সময়ে শেষ হয়:

SELECT *
FROM X_10000 a
CROSS APPLY (SELECT TOP (9223372036854775807) b.ID FROM X_10000 b WHERE a.ID = b.ID) ca
OPTION (LOOP JOIN, MAXDOP 1);

কর্মক্ষেত্র 1

এই ক্যোয়ারিতে একটি সূচক স্পুলও রয়েছে এবং এক সেকেন্ডেরও কম সময়ে শেষ হয়:

SELECT *
FROM X_10000 a
INNER JOIN X_10000 b ON a.ID >= b.ID AND a.ID <= b.ID
OPTION (LOOP JOIN, MAXDOP 1);

workaround 2

মূল ক্যোয়ারিতে সূচকের স্পুল নেই কেন? এমন কোনও দলিলযুক্ত বা অননুমোদিত ইঙ্গিত বা পতাকা চিহ্নিত করার কোনও সেট রয়েছে যা এটিকে একটি সূচক স্পুল দেবে? আমি এই সম্পর্কিত প্রশ্নটি পেয়েছি , তবে এটি আমার প্রশ্নের পুরোপুরি উত্তর দেয় না এবং আমি এই কোয়েরির জন্য রহস্যজনক ট্রেস পতাকা পেতে পারি না।

উত্তর:


20

আপনি জানেন যে, অপ্টিমাইজারের অনুসন্ধান সম্পূর্ণ নয়। এটি এমন জিনিসগুলির চেষ্টা করে যা প্রসঙ্গে বোঝায় এবং যা প্রায়শই বাস্তব প্রশ্নের উপর লভ্যাংশ দেয়। দুটি সিঙ্গল-কলামে আনইনডেক্সড হিপ টেবিলের মধ্যে একটি লুপকে জোর করা এমন পরিস্থিতি নয়। বলেছিল, এখানে কিছু বিবরণ দেওয়া হল:

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

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

অপ্টিমাইজার কোনও প্রয়োগ সক্ষম করতে ফ্লাইতে একটি সূচক তৈরির বিষয়টি বিবেচনা করে না; বরং ইভেন্টের ক্রমটি সাধারণত বিপরীত হয়: প্রয়োগ করতে রূপান্তর করুন কারণ একটি ভাল সূচক বিদ্যমান।

আপনি কখনও কখনও APPLYআপনার ক্যোয়ারিতে সিনট্যাক্স ব্যবহার করে যোগদানের পরিবর্তে কোনও প্রয়োগকে উত্সাহিত করতে পারেন । অপ্রকাশিত ট্রেস পতাকা 9114 এটি একটি যুক্ত-আপ ফ্রন্টের জন্য একটি লজিকাল প্রয়োগ অনুবাদ থেকে অপ্টিমাইজারকে বিযুক্ত করে এটিকে সহায়তা করতে পারে। উদাহরণ স্বরূপ:

SELECT * 
FROM dbo.X_1000 AS a
CROSS APPLY (SELECT * FROM dbo.X_1000 AS b WHERE b.ID = a.ID) AS b
OPTION (QUERYTRACEON 9114);

স্পুল পরিকল্পনা

একটি সূচক স্পুল আবেদনের পক্ষে হয় কারণ বাইরের রেফারেন্স মানে জোড়ের অভ্যন্তরের দিকে নির্বাচনটি প্রয়োগ করা হয়। আপনি প্রায়শই SelToIndexOnTheFlyএটির মাধ্যমে দেখতে পাবেন তবে অন্যান্য পাথ বিদ্যমান। আমার নিবন্ধটি দ্য ইজার সূচক স্পুল এবং অপ্টিমাইজার দেখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.