หัวข้อ: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: xmen256k ที่ 11 กรกฎาคม 2013, 21:51:24 มีเรคคอร์ดอยู่ประมาณ 10,000 อัน และมีสถานะกำกับอยู่
ผมอยากจะสุ่มข้อมูลมาโชว์ 1 อันครับ ไม่ทราบว่า เขียน SQL ยังไงให้คิวรี่ได้เร็วและไม่หนักโฮสบ้าง ปล. ผมลอง โค๊ด: SELECT * FROM table WHERE status ='correct' ORDER BY RAND() LIMIT 1 มันช้าอ่าครับ ขนาดรันใน localhost ใช้เวลาไป 993ms รบกวนหน่อยนะครับ ขอบคุณครับ หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: mikeyx ที่ 11 กรกฎาคม 2013, 21:56:51 โค๊ด: SELECT filed1,filed2,.... FROM table WHERE status ='correct' ORDER BY RAND() LIMIT 1 ทำ index เวลา query ให้ query ตรง ๆไปเลย เช่น $query_tb = mysql_query("SELECT filed1,filed2,.... FROM table WHERE status ='correct' ORDER BY RAND() LIMIT 1"); $show_data = mysql_fetch_array($query_tb); หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: Bigguide ที่ 11 กรกฎาคม 2013, 22:01:52 1.ทำ index ให้ field "status" ดูครับ
2. ถ้า Query เราช้า ให้ลองใช้ explain ดูนะครับ จากตัวอย่าง query คุณ ใช้เป็น explain SELECT * FROM table WHERE status ='correct' ORDER BY RAND() LIMIT 1 หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: goldxp ที่ 11 กรกฎาคม 2013, 22:41:19 SELECT * FROM table WHERE status ='correct' ORDER BY RAND() LIMIT 1
ผมใช้เครื่องpc รุ่นซื้อมา 7 ปีแล้ว run ยังแค่ 16-50 ms ครับ ถ้าต้องการให้เร็วขึ้นลอง set @number = (select max(id) from `table`)*rand(); select * from `table` where status='correct' and id > @number limit 1; อันนี้ใช้เวลาใกล้เคียงกันครับ น่าจะแล้วแต่ว่าเครื่องกำลังทำงานอย่างอื่นด้วยหรือเปล่าซึ่งจะทำให้ช้าลงด้วยครับ :P หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: MapTwoZa ที่ 12 กรกฎาคม 2013, 01:39:42 ถ้า data เยอะๆ order by rand() ไม่ดีแน่ๆครับ ห้ามใช้เด็ดขาดไอ order by rand() อ่ะ
ให้ใช้วิธี random ใน php แล้วไป query เอาครับ เช่นให้ใช้วิธี random ใน php แล้วไป query เอาครับ เช่น $minId = rand(0,10000); $result = mysql_query("SELECT * FROM `table` where id>$minId LIMIT 1"); ** ใช้ > เพื่อกัน missing row ในกรณีเป็น auto increase **** วิธีนี้ต้องรู้ range ของ data ที่แน่นอนครับ แต่ถ้าข้อมูลไม่นิ่ง มีเพิ่มเรื่อยๆ ก็ให้ใช้วิธีนี้ครับ สร้างตารางเป็น memory engine เอาไว้เก็บผลการ random ครับ วิธีนี้จะช้าตอนที่ query ครั้งแรก กับตอน data ในอีก table หมดครับ เช่น ตาราง table กับ tablerand โค๊ด: function queryRandom(){ ** ตาราง table rand ให้มี trid เป็น pk auto increase นะครับ ปล. วิธีที่ 2 อาจจะช้าก็ได้นะ แค่ลองคิดแปลกๆ 55+ แต่คิดว่าน่าจะไวเพราะเอา memory engine มาใช้กับอีกตาราง หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: Nomkhonwaan ที่ 12 กรกฎาคม 2013, 08:32:08 เป็นผมน่ะ
query รอบแรกดึงจำนวน record ทั้งหมดออกมาดูว่ามีกี่ record จากนั้นใช้ php rand() ตัวเลขจากจำนวน record ทั้งหมด แล้ว query รอบสองก็ใช้ limit, offset เอา เช่นสมมติดึงได้ 10k records ก็สั่ง rand()&10000 มันก็จะ random ตัวเลขระหว่าง 0 - 10000 ออกมา ก็เอาไป query แบบนี้ โค๊ด: $offset = rand()&(10000 - 1) :wanwan020: หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: teerdear1 ที่ 12 กรกฎาคม 2013, 08:42:53 ถ้าผมจำไม่ผิด ถ้ามีข้อมูลเป็นแสน แล้วใช้คำสั่ง limit 1
เปลี่ยนเป็น fetch ข้อมูลมาครั้งเดียวจะไวกว่านะครับ ถ้าจำไม่ผิดอ่านะ หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: phurich ที่ 12 กรกฎาคม 2013, 13:25:25 จำเป็นต้องใช้ SQL เท่านั้นเหรอครับ? หาก function Rand() ของ SQL มันช้า ก็ไปหา Algorithm อื่น ของภาษาอื่นมาก็ได้ครับ
ลองหา Algorithm การสุ่มค่าที่เร็วที่สุดในโลกดู พอได้แล้ว ก็ให้มันสุ่มเลขขึ้นมา แล้วคุณก็เอาเลขนั้น ไป select ข้อมูลเลย หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: xmen256k ที่ 12 กรกฎาคม 2013, 20:36:37 เป็นผมน่ะ query รอบแรกดึงจำนวน record ทั้งหมดออกมาดูว่ามีกี่ record จากนั้นใช้ php rand() ตัวเลขจากจำนวน record ทั้งหมด แล้ว query รอบสองก็ใช้ limit, offset เอา เช่นสมมติดึงได้ 10k records ก็สั่ง rand()&10000 มันก็จะ random ตัวเลขระหว่าง 0 - 10000 ออกมา ก็เอาไป query แบบนี้ โค๊ด: $offset = rand()&(10000 - 1) :wanwan020: คือผมก็คิดไว้แบบนี้อ่าครับ แต่มันจะมีปัญหาหรือเปล่า สมมติว่าถ้าช่วงฟิวของ auto increasment มันขาดตอนเช่น 1 2 3 5 6 7 แล้วแรนดอมออกมาเป้น 4 มันจะไปอ้างอิง ฟิว นั้นได้ยังไงอ่าครับ ?? หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: sskzclub ที่ 12 กรกฎาคม 2013, 21:54:49 เข้ามาติดตาม ครับ ^^
หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: xmen256k ที่ 13 กรกฎาคม 2013, 02:47:50 เป็นผมน่ะ query รอบแรกดึงจำนวน record ทั้งหมดออกมาดูว่ามีกี่ record จากนั้นใช้ php rand() ตัวเลขจากจำนวน record ทั้งหมด แล้ว query รอบสองก็ใช้ limit, offset เอา เช่นสมมติดึงได้ 10k records ก็สั่ง rand()&10000 มันก็จะ random ตัวเลขระหว่าง 0 - 10000 ออกมา ก็เอาไป query แบบนี้ โค๊ด: $offset = rand()&(10000 - 1) :wanwan020: คือผมก็คิดไว้แบบนี้อ่าครับ แต่มันจะมีปัญหาหรือเปล่า สมมติว่าถ้าช่วงฟิวของ auto increasment มันขาดตอนเช่น 1 2 3 5 6 7 แล้วแรนดอมออกมาเป้น 4 มันจะไปอ้างอิง ฟิว นั้นได้ยังไงอ่าครับ ?? ผมพอเข้าใจหละครับ ตอนนี้ก็ลองทำดูแล้ว ลดลงเหลือ อยู่ราวๆ 50 ms ปัญหาต่อมาคือผมจะสุ่มมากกว่า 1 อันอ่าครับ ซึ่งลองเปลี่ยน LIMIT xxx,1 จาก 1 เป็น 5 ดู มันกลับให้เป็นข้อมูลที่เรียงลงมากัน ถ้าเป็นไอดีก็จะได้ 4 5 6 7 8 อะไรแบบนี้ ถ้าอยากทำแบบสุ่ม 5 ตัว พอจะมีแนวทางบ้างไหมครับ หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: cloudsphere ที่ 13 กรกฎาคม 2013, 09:49:23 เข้ามาเก็บข้อมูล :wanwan003: :wanwan017:
หัวข้อ: Re: [PHP,SQL] จะ random เรคคอร์ดอย่างไรให้รวดเร็ว ??? เริ่มหัวข้อโดย: คนธรรมดา ที่ 13 กรกฎาคม 2013, 10:55:57 เป็นผมน่ะ query รอบแรกดึงจำนวน record ทั้งหมดออกมาดูว่ามีกี่ record จากนั้นใช้ php rand() ตัวเลขจากจำนวน record ทั้งหมด แล้ว query รอบสองก็ใช้ limit, offset เอา เช่นสมมติดึงได้ 10k records ก็สั่ง rand()&10000 มันก็จะ random ตัวเลขระหว่าง 0 - 10000 ออกมา ก็เอาไป query แบบนี้ โค๊ด: $offset = rand()&(10000 - 1) :wanwan020: คือผมก็คิดไว้แบบนี้อ่าครับ แต่มันจะมีปัญหาหรือเปล่า สมมติว่าถ้าช่วงฟิวของ auto increasment มันขาดตอนเช่น 1 2 3 5 6 7 แล้วแรนดอมออกมาเป้น 4 มันจะไปอ้างอิง ฟิว นั้นได้ยังไงอ่าครับ ?? ผมพอเข้าใจหละครับ ตอนนี้ก็ลองทำดูแล้ว ลดลงเหลือ อยู่ราวๆ 50 ms ปัญหาต่อมาคือผมจะสุ่มมากกว่า 1 อันอ่าครับ ซึ่งลองเปลี่ยน LIMIT xxx,1 จาก 1 เป็น 5 ดู มันกลับให้เป็นข้อมูลที่เรียงลงมากัน ถ้าเป็นไอดีก็จะได้ 4 5 6 7 8 อะไรแบบนี้ ถ้าอยากทำแบบสุ่ม 5 ตัว พอจะมีแนวทางบ้างไหมครับ ทำได้แล้วก็ใช้วิธี Loop |