অন্যান্য উত্তরগুলি সিনট্যাক্সের পার্থক্যগুলি বেশ ভালভাবে কভার করে তাই আমি এর মধ্যে যাব না। পরিবর্তে এই উত্তরটি কেবল ওরাকলে সম্পাদন করবে।
ওরাকল অপ্টিমাইজারটি কোনও সিটিইর ফলাফলগুলি অভ্যন্তরীণ অস্থায়ী সারণিতে পরিণত করতে পারে। এটি ব্যয়ভিত্তিক অপ্টিমাইজেশনের পরিবর্তে এটি করার জন্য একটি হিউরিস্টিক ব্যবহার করে। হিউরিস্টিক এমন একটি বিষয় যা "সিটিইকে মেকারাইজেশন করুন যদি এটি তুচ্ছ প্রকাশ না হয় এবং সিটিই কোয়েরিতে একাধিকবার রেফারেন্স হয়"। কিছু প্রশ্ন রয়েছে যার জন্য বস্তুগতকরণ কার্যকারিতা উন্নত করবে। কিছু প্রশ্ন রয়েছে যার জন্য বস্তুতীকরণ নাটকীয়ভাবে কর্মক্ষমতা হ্রাস করবে। নীচের উদাহরণটি কিছুটা স্বীকৃত তবে এটি বিষয়টিকে ভালভাবে তুলে ধরে:
প্রথমে একটি প্রাথমিক কী সহ একটি টেবিল তৈরি করুন যাতে 1 থেকে 10000 পর্যন্ত পূর্ণসংখ্যা থাকে:
CREATE TABLE N_10000 (NUM_ID INTEGER NOT NULL, PRIMARY KEY (NUM_ID));
INSERT /*+APPEND */ INTO N_10000
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= 10000
ORDER BY LEVEL;
COMMIT;
দুটি উত্সযুক্ত টেবিল ব্যবহার করে নিম্নলিখিত কোয়েরি বিবেচনা করুন:
SELECT t1.NUM_ID
FROM
(
SELECT n1.NUM_ID
FROM N_10000 n1
CROSS JOIN N_10000 n2
) t1
LEFT OUTER JOIN
(
SELECT n1.NUM_ID
FROM N_10000 n1
CROSS JOIN N_10000 n2
) t2 ON t1.NUM_ID = t2.NUM_ID
WHERE t1.NUM_ID <= 0;
আমরা এই ক্যোয়ারির দিকে নজর দিতে পারি এবং দ্রুত নির্ধারণ করতে পারি যে এটি কোনও সারি ফিরবে না। ওরাকল সূচিটিও তা নির্ধারণ করতে সক্ষম হতে হবে। আমার মেশিনে ক্যোয়ারীটি নিম্নলিখিত পরিকল্পনার সাথে প্রায় তাত্ক্ষণিকভাবে শেষ করে:
আমি নিজেকে পুনরাবৃত্তি করতে পছন্দ করি না, সুতরাং আসুন আমরা একটি সিটিই দিয়ে একই ক্যোয়ারী চেষ্টা করি:
WITH N_10000_CTE AS (
SELECT n1.NUM_ID
FROM N_10000 n1
CROSS JOIN N_10000 n2
)
SELECT t1.NUM_ID
FROM N_10000_CTE t1
LEFT JOIN N_10000_CTE t2 ON t1.NUM_ID = t2.NUM_ID
WHERE t1.NUM_ID <= 0;
পরিকল্পনাটি এখানে:
এটা সত্যিই খারাপ পরিকল্পনা। সূচকটি ব্যবহার করার পরিবর্তে, ওরাকল 10000 এক্স 10000 = 100000000 সারিগুলিকে কেবল টেম্প টেবিলের মধ্যে অবশেষে 0 টি সারি ফিরিয়ে আনতে সক্ষম করে। এই পরিকল্পনার ব্যয় 6 এম এর কাছাকাছি যা অন্যান্য প্রশ্নের তুলনায় অনেক বেশি। ক্যোয়ারীটি আমার মেশিনে শেষ হতে 68 সেকেন্ড সময় নিয়েছে।
নোট করুন যে টেম্প টেবিল স্পেসে পর্যাপ্ত মেমরি বা খালি জায়গা না থাকলে ক্যোয়ারীটি ব্যর্থ হতে পারে।
INLINE
সিটিই বাস্তবায়ন থেকে অপ্টিমাইজারটিকে অস্বীকার করার জন্য আমি অনিবন্ধিত ইঙ্গিতটি ব্যবহার করতে পারি :
WITH N_10000_CTE AS (
SELECT /*+ INLINE */ n1.NUM_ID
FROM N_10000 n1
CROSS JOIN N_10000 n2
)
SELECT t1.NUM_ID
FROM N_10000_CTE t1
LEFT JOIN N_10000_CTE t2 ON t1.NUM_ID = t2.NUM_ID
WHERE t1.NUM_ID <= 0;
এই ক্যোয়ারী সূচকটি ব্যবহার করতে সক্ষম এবং প্রায় তাত্ক্ষণিকভাবে শেষ হয়। ক্যোয়ারির ব্যয় আগের মতোই, ১১। সুতরাং দ্বিতীয় কোয়েরির জন্য, ওরাকল দ্বারা ব্যবহৃত হিউরিস্টিকটির ফলস্বরূপ এটি 11 এর আনুমানিক ব্যয় সহ একটি কোয়েরির পরিবর্তে 6 এম ব্যয় করে একটি কোয়েরিকে বেছে নিয়েছিল।
WITH...
)। আপনি প্রতিটি