[ PHP + MS SQL ] ข้อมูลก้อนใหญ่มากกก ใน .net ใช้ DataSet แล้วฝั่ง PHP ต้องเขียนยังไงครับ?

เริ่มโดย saparee, 15 กันยายน 2011, 16:29:48

หัวข้อก่อนหน้า - หัวข้อถัดไป

0 สมาชิก และ 1 ผู้มาเยือน กำลังดูหัวข้อนี้

saparee

ผมไม่แน่ใจว่าตั้งคำถามถูกหรือเปล่า

คืองี้ครับ กำลังทำงานกับข้อมูลก้อนใหญ่มาก
query ข้อมูลแต่ละครั้งใช้เวลาเฉลี่ย 32-37วิ/หน้า

สมมติ มีตาราง 3 อัน แต่ละอันก็มีย่อยๆลงไปอีก ฉะนั้น เลยยิ่งเกิดการเรียก query หลายครั้งมากเข้าไปใหญ่ เลยทำให้ใช้เวลานาน(มั้ง)ครับ (พูดตามความเข้าใจนะครับ)
พยายามเจาะลงไปก็แล้ว ใส่ where กระจุยกระจายเลย เพื่อให้ได้ข้อมูลเป๊ะๆออกมา ผลคือก็ยังไม่เร็วขึ้นเท่าไหร่

ตอนนี้เหลือแต่ลองแบ่งก้อน database ออกเป็นส่วนๆนี่แหละครับที่ยังไม่ได้ลอง  :P

ผมเลยสงสัยว่า ถ้าต้องการจะทำในลักษณะคล้าย .net หล่ะครับ (ที่มี dataset)
ประมาณว่าไหนๆก็ต้องโหลดแล้ว เลยขอโหลดครั้งแรกครั้งเดียวมาได้ก้อนใหญ่ไปเลย (อาจจะไม่ได้หมายถึงว่าจะใช้ select * นะครับ)
แล้วเวลาเรียกใช้ก็ค่อยมาใส่ if..else ดึงออกมาจากข้อมูลก้อนนั้นเองอีกที จะได้ไม่ต้องคอยโหลดหลายครั้ง แล้วถ้าต้องการข้อมูลที่ปัจจุบันกว่าก็ค่อย reload กันใหม่ (หรือแบบนี้เขาเรียกว่า Temp หว่า?)  

^
^
^
ถ้าทำแบบนี้จะทำให้เร็วกว่าหรือเปล่าครับ?

ขอคำแนะนำด้วยนะครับ


ปล. ตอนนี้ผมใช้ Codeigniter และพยายามหัดใช้ Ajax เข้ามาช่วยในบางจุดครับ



หมายเหตุ:  แก้ไขข้อมูลที่นำเสนอผิดครับ

marus


thenetxx

ใหญ่มากนี่แค่ไหนครับ กี่ล้าน records ครับ

หน้านึง 8 วินาที นี่ query กี่ครั้งครับ

แยกเป็นเรื่อง ๆ ก่อนนะครับ เปิด page ช้า กับ query ช้า

เบื้องต้นจัดการ query ก่อน การทำ index ให้กับข้อมูล จะทำให้เร็วขึ้น ลอง denomalize ออกมาเป็น Table ย่อย ๆ

ในบางกรณี query เล็ก ๆ หลายครั้งจนได้ข้อมูลครบ เป็นเรื่องดีกว่า query แบบ where อลังการครั้งเดียวครับ ^^
Develop site but can't develop life
ASIA

saparee

อ้างถึงจาก: thenetxx ใน 15 กันยายน 2011, 20:13:36
ใหญ่มากนี่แค่ไหนครับ กี่ล้าน records ครับ

หน้านึง 8 วินาที นี่ query กี่ครั้งครับ

แยกเป็นเรื่อง ๆ ก่อนนะครับ เปิด page ช้า กับ query ช้า

เบื้องต้นจัดการ query ก่อน การทำ index ให้กับข้อมูล จะทำให้เร็วขึ้น ลอง denomalize ออกมาเป็น Table ย่อย ๆ

ในบางกรณี query เล็ก ๆ หลายครั้งจนได้ข้อมูลครบ เป็นเรื่องดีกว่า query แบบ where อลังการครั้งเดียวครับ ^^

เท่าที่ไล่ดู จะมีการ join table เยอะมากครับ (เป็นโปรเจคที่พัฒนามาจากทีมงานก่อนหน้าผมเขาทำไว้ครับ)

ส่วนเรื่องเวลาผมขอแก้ไขตัวเลขนิดนึงครับ เหมือนจะให้ข้อมูลผิดไป คือที่ 8วิ เป็นครั้งที่ทำได้เร็วที่สุดครับ ส่วนนอกนั้น เฉลี่ยจะอยู่ที่ 32-37วินาที ต่อการเรียก 1 ครั้งครับ  :wanwan009:

ลองดูเรื่อง page load speed ดูแล้วครับ ใน script ส่วนอื่นมีการโหลด เสร็จทั้งหน้าตั้งแต่ 1-2วิแรกแล้วครับ ส่วนเวลาที่เหลือมันคือตอน  query ออกมาแสดงผลล้วนๆเลยครับ

ขอบคุณสำหรับคำแนะนำครับ โดยตอนนี้ผมกำลังหาข้อมูลเกี่ยวกับการทำ index ข้อมูลคัรบ ถ้าได้เรื่องอย่างไรแล้วจะกลับมาอัพเดทนะครับ

ขอบคุณครับ

saparee

ตอนนี้ยังแก้ไขปัญหาไม่ได้ครับ แต่เกิดข้อสงสัยเลยขอกลับมาฝากคำถามทิ้งไว้ก่อน

คือ ผมเข้าใจว่าการทำ index ให้กับข้อมูล เป็นการทำที่ฝั่ง database แล้วถ้าในกรณีที่ผมไม่สามารถเข้าไปยุ่งกับ database ได้หล่ะครับ จะมีวิธีอื่นอีกหรือเปล่าครับ ?
( ยังไม่ได้ลองคุยกับหัวหน้า แต่ค่อนข้างมั่นใจว่าอยู่นอกเหนือความรับผิดชอบ  :'( )




qwerty

เคยเจอปัญหานี้เหมือนกัน ส่วนใหญ่ต้องไปแก้ 2 จุด คือ คำสั่ง query กับตัว database เอง เช่น selectเฉพาะ field ที่ต้องการจริงๆ ลดการใช้ group by และ sort ถ้ายังไม่หายอีก ก็อาจเป็นที่ตัว database ครับ เพราะบาง table ไม่ได้มีการจัด index ไว้ดีพอ เช่น ถ้าคุณ where field xxx แต่ตารางของคุณไม่ได้มีการทำ index ไว้ มันก็จะวิ่งไปทุก record มี 8 ล้าน ก็วิ่งเต็มจำนวน ถ้ามี index อาจจะวิ่งแค่ 1 ล้าน เพราะฉะนั้นพวก where ต่างๆ ลองเช็คดูว่าสามารถ where จาก filed ที่มี index ก่อนได้หรือป่าว หลังจากนั้นค่อยใช้ php หรือ query กรองผลลัพธ์อีกทีก็ว่ากันไป
พวกคำสั่ง query ลองใส่คำสั่ง explain select .... from ... ข้างหน้าคำสั่งดู จะได้รู้ว่ามันวิ่งไปกี่ตาราง ใช้ index หรือป่าว ที่มันช้าเป็นเพราะตารางไหน
หรือถ้าเกิดข้อมูลที่คุณ query มามันไม่ได้อัพเดทบ่อยก็เก็บเป็น cache ไว้ก็ได้ครับ อันนี้ง่ายสุดแล้ว แล้วจะอัพเดททุก 1 ชั่วโมง อะไรแบบนี้ก็ได

qwerty

ตรงส่วนหน้าเว็บ มีการแสดงผลที่ต้องใช้ database เยอะหรือป่าว ถ้าไม่มาก ก็ลองให้มันโหลดหน้าเว็บเสร็จก่อนครับ แล้วใช้ ajax ไปเรียกไฟล์ php ที่ใช้query ข้อมูลมา พอquery เสร็จแล้วค่อยแสดงผลหน้าเว็บ ไอ้ตรงส่วนที่มันรอโหลดอยู่ อาจจะใส่รูปหมุนๆ ไว้ก็ได้ให้รู้ว่าโหลดอยู่

saparee

อ้างถึงจาก: qwerty ใน 16 กันยายน 2011, 10:20:00
ตรงส่วนหน้าเว็บ มีการแสดงผลที่ต้องใช้ database เยอะหรือป่าว ถ้าไม่มาก ก็ลองให้มันโหลดหน้าเว็บเสร็จก่อนครับ แล้วใช้ ajax ไปเรียกไฟล์ php ที่ใช้query ข้อมูลมา พอquery เสร็จแล้วค่อยแสดงผลหน้าเว็บ ไอ้ตรงส่วนที่มันรอโหลดอยู่ อาจจะใส่รูปหมุนๆ ไว้ก็ได้ให้รู้ว่าโหลดอยู่

ใช่ครับ ตอนนี้ผมทำเป็นลักษณะแบบนี้อยู่ครับ
แต่ก็นั่นแหละครับ หมุนตี้วๆๆอยู่นานเลยกว่าข้อมูลจะมา  :wanwan044:

thenetxx

ถ้าแต่ต้อง DB ไม่ได้

แนะนำให้ทำ cache ไว้ที่ฝั่งเว็บ อาจจะเขียนสคริปไว้ตัวนึง แล้วใช้ crond เพื่อ get data มาเก็บข้อมูลเป็น Array (เข้ารหัส Json หรือ Serialize ก็ได้)แล้ว Cache ไว้ แล้วตอนใช้ก็ดึงจาก Cache มา Decode แล้วแสดงครับ
Develop site but can't develop life
ASIA

execter

อ้างถึงจาก: saparee ใน 15 กันยายน 2011, 16:29:48
ผมไม่แน่ใจว่าตั้งคำถามถูกหรือเปล่า

คืองี้ครับ กำลังทำงานกับข้อมูลก้อนใหญ่มาก
query ข้อมูลแต่ละครั้งใช้เวลาเฉลี่ย 32-37วิ/หน้า

สมมติ มีตาราง 3 อัน แต่ละอันก็มีย่อยๆลงไปอีก ฉะนั้น เลยยิ่งเกิดการเรียก query หลายครั้งมากเข้าไปใหญ่ เลยทำให้ใช้เวลานาน(มั้ง)ครับ (พูดตามความเข้าใจนะครับ)
พยายามเจาะลงไปก็แล้ว ใส่ where กระจุยกระจายเลย เพื่อให้ได้ข้อมูลเป๊ะๆออกมา ผลคือก็ยังไม่เร็วขึ้นเท่าไหร่

ตอนนี้เหลือแต่ลองแบ่งก้อน database ออกเป็นส่วนๆนี่แหละครับที่ยังไม่ได้ลอง  :P

ทำแบบนี้มันจะไม่กินแรมกระฉูดเลยเหรอครับ  :wanwan044:
ผมเลยสงสัยว่า ถ้าต้องการจะทำในลักษณะคล้าย .net หล่ะครับ (ที่มี dataset)
ประมาณว่าไหนๆก็ต้องโหลดแล้ว เลยขอโหลดครั้งแรกครั้งเดียวมาได้ก้อนใหญ่ไปเลย (อาจจะไม่ได้หมายถึงว่าจะใช้ select * นะครับ)
แล้วเวลาเรียกใช้ก็ค่อยมาใส่ if..else ดึงออกมาจากข้อมูลก้อนนั้นเองอีกที จะได้ไม่ต้องคอยโหลดหลายครั้ง แล้วถ้าต้องการข้อมูลที่ปัจจุบันกว่าก็ค่อย reload กันใหม่ (หรือแบบนี้เขาเรียกว่า Temp หว่า?)


^
^
^
ถ้าทำแบบนี้จะทำให้เร็วกว่าหรือเปล่าครับ?

ขอคำแนะนำด้วยนะครับ


ปล. ตอนนี้ผมใช้ Codeigniter และพยายามหัดใช้ Ajax เข้ามาช่วยในบางจุดครับ



หมายเหตุ:  แก้ไขข้อมูลที่นำเสนอผิดครับ

Mubaza Thailand

bonshington

1 tune query
- ใส่ index ให้ครบตามเงื่อนไขที่แสดง และตาม foreign key ต่างๆ
- พวก varchar(น้อย) และซ้ำๆ ไม่ต้อง index นะ เช่น  STTS varchar(6) ACTIVE, NORMAL, CLOSE พวกนี้ อย่าใส่ index
- condition เอา function ออก เช่น where coalesce (a, b) = 10 ให้เปลี่ยนเป็น where (a is null or a = 10) and (b is null or b = 10)
- เอาเงื่อนไขตัวเลขมาไว้ต้นๆ ของ condition
- ใช้ and เยอะๆ
- บางกรณี ถ้ามี or ให้เปลี่ยนเป็น union จะเร็วกว่ามาก เช่น select * from a where aa = 1 or ab = 2 ให้เปลี่ยนเป็น select * from a where aa = 1 union select * from a where ab = 2 อันนี้ คอนเฟิมว่าเร็วกว่า เทสมาแล้ว
- ตัด dynamic query ออก พวกนี้devโบราณจะอ้างว่าเร็วกว่า โม้ทั้งเพ
- ถ้ามี order by แบบ  dymaic ให้ใช้ case when บน order by เช่น order by case when order_col = 1 then aa when order_col = 2 then ab else ... end;
- ในการแสดงผล ถ้า table.column ไหนไม่ออกในผลลัพธ์ หรือปรากดในเงื่อนไขครั้งเดียว ให้ใช้เป็น subquery ไป เช่น select * from a where aa in (select pk from b)

2 tune app
- การดึงข้อมูลหมื่นบรรทัด แต่เอามาแสดงแค่ 20-50 บรรทัดก็เสียเปล่าอยู่ ใส่ cursor ให้มันซักหน่อย ดึงเฉพาะ row ที่จะเอาออกมาแสดง
- dev.net โบราณๆ จะเอา dataTable ยัดลง viewstate โง่มากขอบอก บางทีมี row เป็นพันเป้นหมื่น ตายกันไปข้างนึง

-

supachet2526

อีกทางหนึ่งต้อง tuning ตัว database ครับ
เช่น
sort_buffer_size = ????M
read_buffer = ?M
write_buffer = ?M
และตัวอื่นๆครับลองศึกษาดูครับ
จะเร็วสุดยอดครับถ้า server แรงครับ
แต่ถ้า server ไม่ใช้ของเราก็อดครับ
[direct=https://www.webunique.in.th]รับเขียนเว็บไซต์ [/direct]
[direct=https://www.webunique.in.th]บริษัทรับออกแบบเว็บไซต์ [/direct]

[direct=https://www.baansecondhand.com]ขายบ้านมือสอง[/direct]

ถ้าคุณลงมือทำในสิ่งที่คุณสนใจอยู่เสมอ อย่างน้อยจะมีคนคนหนึ่งที่พอใจ