আমি আমার প্রকল্পে বিদ্যমান প্রচুর প্রশ্নগুলি অনুকূল করে তুলছি। কাসনসুইয়ের সমাধান আমাকে ক্যোয়ারীগুলিকে অনেক গতিতে সাহায্য করেছে! তবে, আমি সমস্ত প্রশ্নের মধ্যে উল্লিখিত সমাধানটি সংযুক্ত করা কঠিন বলে মনে করি, বিশেষত একাধিক বৃহত টেবিলগুলিতে অনেকগুলি সাব-কোয়েরিতে জড়িত জটিল প্রশ্নের জন্য।
সুতরাং আমি একটি কম অপ্টিমাইজড সমাধান ব্যবহার করছি। মূলত এটি কাসনসুইয়ের সমাধান হিসাবে একইভাবে কাজ করে।
SELECT accomodation.ac_id,
accomodation.ac_status,
accomodation.ac_name,
accomodation.ac_status,
accomodation.ac_images
FROM accomodation, accomodation_category
WHERE accomodation.ac_status != 'draft'
AND accomodation.ac_category = accomodation_category.acat_id
AND accomodation_category.acat_slug != 'vendeglatohely'
AND ac_images != 'b:0;'
AND rand() <= $size * $factor / [accomodation_table_row_count]
LIMIT $size
$size * $factor / [accomodation_table_row_count]
এলোমেলো সারি বাছাইয়ের সম্ভাবনাটি কাজ করে। র্যান্ড () একটি এলোমেলো সংখ্যা তৈরি করবে। সারিটি নির্বাচন করা হবে যদি র্যান্ড () ছোট হয় বা সম্ভাবনার সমান হয়। এটি কার্যকরভাবে সারণির আকার সীমাবদ্ধ করতে একটি এলোমেলো নির্বাচন সম্পাদন করে। যেহেতু সম্ভাবনা রয়েছে এটি নির্ধারিত সীমা গণনার চেয়ে কম ফিরে আসবে, তাই আমরা পর্যাপ্ত সারি নির্বাচন করছি তা নিশ্চিত করার জন্য আমাদের সম্ভাবনা বাড়ানো দরকার। অতএব আমরা $ আকারকে $ গুণক দ্বারা গুণ করি (আমি সাধারণত I গুণক = 2 সেট করি, বেশিরভাগ ক্ষেত্রে কাজ করে)। অবশেষে আমরাlimit $size
সমস্যা এখন আবাসন_সমাজ_সামগ্রী_কাউন্টটি কাজ করছে । যদি আমরা টেবিলের আকারটি জানি তবে আমরা টেবিলের আকারটি হার্ড কোড করতে পারি। এটি দ্রুততম চলবে, তবে অবশ্যই এটি আদর্শ নয়। আপনি যদি মাইসাম ব্যবহার করছেন তবে টেবিলের গণনা পাওয়া খুব কার্যকর। যেহেতু আমি ইনোডাব ব্যবহার করছি, আমি কেবল একটি সাধারণ গণনা + নির্বাচন করছি। আপনার ক্ষেত্রে এটি দেখতে এই রকম হবে:
SELECT accomodation.ac_id,
accomodation.ac_status,
accomodation.ac_name,
accomodation.ac_status,
accomodation.ac_images
FROM accomodation, accomodation_category
WHERE accomodation.ac_status != 'draft'
AND accomodation.ac_category = accomodation_category.acat_id
AND accomodation_category.acat_slug != 'vendeglatohely'
AND ac_images != 'b:0;'
AND rand() <= $size * $factor / (select (SELECT count(*) FROM `accomodation`) * (SELECT count(*) FROM `accomodation_category`))
LIMIT $size
জটিল অংশটি সঠিক সম্ভাবনার বাইরে চলেছে। আপনি দেখতে পাচ্ছেন যে নীচের কোডটি কেবলমাত্র রুক্ষ টেম্প টেবিলের আকারটি গণনা করে (বাস্তবে, খুব রুক্ষ!): (select (SELECT count(*) FROM accomodation) * (SELECT count(*) FROM accomodation_category))
তবে আপনি টেবিলের আকার আরও কাছাকাছি রাখতে এই যুক্তিকে পরিমার্জন করতে পারেন। নোট করুন যে সারিগুলি নীচে-নির্বাচনের চেয়ে ওভার-সিলেক্ট করা ভাল। উদাহরণস্বরূপ, যদি সম্ভাবনাটি খুব কম সেট করা থাকে তবে আপনি পর্যাপ্ত সারিটি না বেছে নেওয়ার ঝুঁকি নিয়ে যান।
আমাদের টেবিলের আকারটি পুনরায় গণনা করা দরকার বলে এই সমাধানটি কাসনোইয়ের সমাধানের চেয়ে ধীরে চলে। যাইহোক, আমি এই কোডিংটি অনেক বেশি পরিচালনাযোগ্য বলে মনে করি। এটি নির্ভুলতা + কার্য সম্পাদন বনাম কোডিং জটিলতার মধ্যে একটি বাণিজ্য । এটি বলার পরেও, বড় টেবিলগুলিতে এটি এখনও অর্ডার বাই র্যান্ডের () এর চেয়ে অনেক বেশি দ্রুত।
দ্রষ্টব্য: যদি ক্যোয়ারির যুক্তি অনুমতি দেয় তবে যেকোন যোগদানের ক্রিয়াকলাপের আগে যত তাড়াতাড়ি সম্ভব এলোমেলো নির্বাচন সম্পাদন করুন।