ฉันกำลังเพิ่มประสิทธิภาพการสืบค้นที่มีอยู่จำนวนมากในโครงการของฉัน โซลูชันของ Quassnoi ช่วยให้ฉันเร่งการค้นหาได้มาก! อย่างไรก็ตามฉันพบว่าเป็นการยากที่จะรวมโซลูชันดังกล่าวไว้ในแบบสอบถามทั้งหมดโดยเฉพาะอย่างยิ่งสำหรับการสืบค้นที่ซับซ้อนซึ่งเกี่ยวข้องกับการสืบค้นย่อยจำนวนมากในตารางขนาดใหญ่หลาย ๆ
ดังนั้นฉันจึงใช้โซลูชันที่เหมาะสมน้อยกว่า โดยพื้นฐานแล้วจะทำงานในลักษณะเดียวกับโซลูชันของ Quassnoi
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]
คำนวณความน่าจะเป็นของการเลือกแถวสุ่ม Rand () จะสร้างตัวเลขสุ่ม แถวนี้จะถูกเลือกถ้า rand () เล็กกว่าหรือเท่ากับความน่าจะเป็น วิธีนี้ดำเนินการเลือกแบบสุ่มอย่างมีประสิทธิภาพเพื่อ จำกัด ขนาดตาราง เนื่องจากมีโอกาสที่จะคืนค่าน้อยกว่าจำนวน จำกัด ที่กำหนดไว้เราจึงต้องเพิ่มความน่าจะเป็นเพื่อให้แน่ใจว่าเราเลือกแถวได้เพียงพอ ดังนั้นเราจึงคูณ $ size ด้วย $ factor (โดยปกติฉันจะตั้งค่า $ factor = 2 ซึ่งใช้ได้ในกรณีส่วนใหญ่) ในที่สุดเราก็ทำlimit $size
ตอนนี้ปัญหากำลังดำเนินการในการแก้ไขค่าfacodation_table_row_count accomodation_table_row_countถ้าเราทราบขนาดตารางเราสามารถกำหนดขนาดตารางได้ยาก สิ่งนี้จะทำงานได้เร็วที่สุด แต่เห็นได้ชัดว่านี่ไม่เหมาะ หากคุณใช้ Myisam การนับตารางจะมีประสิทธิภาพมาก เนื่องจากฉันใช้ innodb ฉันแค่ทำการนับ + การเลือกแบบธรรมดา ในกรณีของคุณจะมีลักษณะดังนี้:
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))
แต่คุณสามารถปรับแต่งตรรกะนี้เพื่อให้ได้ค่าประมาณขนาดตารางที่ใกล้ขึ้นโปรดทราบว่าการเลือก OVER จะดีกว่าการเลือกแถวใต้ กล่าวคือหากตั้งค่าความน่าจะเป็นต่ำเกินไปคุณมีความเสี่ยงที่จะเลือกแถวไม่เพียงพอ
โซลูชันนี้ทำงานช้ากว่าโซลูชันของ Quassnoi เนื่องจากเราต้องคำนวณขนาดตารางใหม่ อย่างไรก็ตามฉันพบว่าการเข้ารหัสนี้จัดการได้ง่ายกว่ามาก นี่เป็นการแลกเปลี่ยนระหว่างความแม่นยำ + ประสิทธิภาพและความซับซ้อนในการเข้ารหัสการเข้ารหัสความซับซ้อนต้องบอกว่าบนโต๊ะขนาดใหญ่ยังเร็วกว่า Order by Rand () มาก
หมายเหตุ: ถ้าตรรกะของแบบสอบถามอนุญาตให้ทำการเลือกแบบสุ่มโดยเร็วที่สุดก่อนที่จะดำเนินการรวมใด ๆ