Tutorial

กราบละ เลิกใช้ Select * สักที !

By Arnon Puitrakul - 10 สิงหาคม 2022

กราบละ เลิกใช้ Select * สักที !

เมื่อหลายวันก่อน เรามานั่งอ่าน Code ชุดนึง แล้วทำให้นึกขึ้นมาได้แบบ จัง ๆ อ่านแล้วกำหมัด แต่ก็นะ เมื่อก่อนเราก็ทำเหมือนกัน คือการใช้ * หรือ Star ตอนที่เรา Select ข้อมูลผ่าน SQL Command เราจะบอกว่า เลิกเถอะนะ ทำไมเราลองไปดูเหตุผลกัน

Select Command

เริ่มจากพื้นฐานกันก่อนละกัน คำสั่งที่เราใช้ในการดึงข้อมูล หรือ Query ข้อมูลออกจากพวก Relational Database ทั้งหลาย เราจะใช้ SELECT Command กัน ซึ่ง Syntax ของมันง่ายมาก ๆ

SELECT [Fields] FROM [Table Name];

คือ เราใช้ Select แล้วตามด้วย Field ที่เราต้องการดึง ถ้าเราอยากได้ทุกช่องเลย เราก็จะใส่เป็น Star เข้าไป แล้วตามด้วย From กับชื่อ Table ที่เราต้องการดึงมา

เราอาจจะใส่เป็น Where เข้าไปต่อ เพื่อสร้างเงื่อนไขในการดึง หรืออาจจะใช้ Join เพื่อจับคู่กับ Table อื่น ๆ ได้อีก อันนี้ลองเข้าไปอ่านในพวก DML Command ใน SQL ได้

Star ผิดตรงไหน ?

อย่างที่เราบอกว่า Star คือการที่เราจะเอาทุก Column ของ Table มาหมดเลย เราโอเคนะ ถ้าเกิดเราดึงมาทุก Column แล้วเรามีการเรียกใช้ทั้งหมด แต่ถ้าเราบอกว่า เราดึงออกมา 10 Field แล้วเราใช้อยู่แล้ว 2 Field แบบนี้แหละที่เราว่า ชิบหายแน่นอน

ก่อนที่เราจะไปถึง Level ของ Database นะ เราเอา Level ของโปรแกรมเราก่อน ถ้าเราล่อ 10 Field นั่นออกมา หลังจาก Database โยนกลับไปให้โปรแกรมเราแล้ว มันก็จะต้องเก็บลงไปในตัวแปร และแน่นอนว่า มันก็จะต้องเก็บลง Memory เราแน่นอน ดังนั้น โปรแกรมของเราจะกิน Memory ทั้ง ๆ ที่มันไม่จำเป็นเลย โดยเฉพาะในอุปกรณ์เล็ก ๆ ที่มี Memory ขนาดเล็ก

ยังไม่นับว่า ถ้า Database Server กับ Consumer อยู่คนละที่กัน แล้วข้อมูลจาก Database จะต้องโยนไปที่ Consumer ก็จะทำให้เสียเวลา และ เสีย Data เยอะเข้าไปอีก เช่น เราบอกว่า เราเขียน App บน Mobile ให้ไป Query Database ออกมาสักตัวนึง เราใช้อยู่ไม่กี่อันเช่น เราใช้ข้อมูลอยู่นับเป็นสัก 2 kB แต่เราโหลดมาจริง 2 MB เรียกว่าหลายเท่าเลยนะ

อ่านดูแล้วก็แค่โปรแกรมเราใช้ Memory เยอะ งั้นเรามาฝั่งที่สนุกกันบ้าง นั่นคือฝั่ง Database Server อันนี้แหละ พีค เพราะถ้าเราดึงส่วนที่เราไม่ได้ใช้งานออกมาเยอะ นั่นแปลว่า ตอนที่เรา Query เครื่องมันจะต้องดึงข้อมูลเยอะกว่าที่เราจะต้องใช้เยอะมาก ยังไม่นับว่า Table ที่เรา Query มันมี ข้อมูลมหาศาลมาก ๆ หลายล้าน Record พวกนี้ ถ้าเครื่องไม่แรง แล้วเราล่อแบบนี้ก็คือ อาจจะใช้เวลาในการ Query ที่นานกว่าที่ควรจะเป็น จนไปถึงเครื่องเอาไม่อยู่แล้วแตกได้เลย

ไหน ๆ เราพูดถึง Join แล้ว อันนี้แหละ อร่อยเข้าไปอีก เช่นเราบอกว่า เรามี 2 Table ที่มี Field สัก 20 Fields กับอีก Table มีสัก 30 Fields เรา Join กันทำให้เราจะมีทั้งหมด 49 Fields ด้วยกัน เรียกได้ว่า มันสร้างภาระให้กับเครื่อง Database Server หนักกว่าที่ควรจะเป็นมาก ๆ

เมื่อไหร่ที่เราควรใช้ Star ?

พูดมาขนาดนี้ ก็อาจจะทำให้หลาย ๆ คนถามว่า อ้าว แล้วถ้ามันไม่โอเคขนาดนี้ ทำไม SQL ถึงมี Star มาเป็น Shorthand ให้เราใช้ได้ นั่นก็เพราะบางครั้ง มันจะมีเคสที่เราจะต้องใช้ทุก Columns ของ Table แน่นอน พวกนี้แหละ ทำให้เราสามารถเขียนคำสั่งได้ง่ายขึ้น ไม่ต้องยืดยาวมาก

ถ้าเราใช้ทุก Columns นั่นแปลว่า ไม่ว่าเราจะใช้ Star หรือ เราจะเขียนชื่อ Field ทั้งหมดของ Table ยังไง ๆ ค่ามันก็เท่ากันอยู่ดี แค่นั้นเลย

สรุป

การใช้งาน Star ในคำสั่ง Select เอาจริง ๆ มันก็ไม่ได้ผิด ถ้าเราต้องการทุก Column มาใช้งานจริง ๆ แต่ ถ้าเราบอกว่า เราไม่ต้องการใช้ทั้งหมด เราแนะนำให้ทำการใส่ไปบอกมันเลยว่า เราต้องการ Field ไหนบ้าง เพื่อที่ Database Server จะได้เอาออกมาให้แค่เท่าที่เราใช้ ลดโหลดที่จะเกิดขึ้นกับ Database Server และ Client เองด้วย พร้อมทั้ง ถ้าข้อมูลไม่วิ่งออกมานั่นหมายถึงความปลอดภัยที่ดีขึ้น เอาเฉพาะที่ใช้กันมาพอเนอะ

แถม : หัดใช้ Limit ด้วยเด้อ

เมื่อครู่ เราพูดถึงด้าน Column โดยการให้เราใส่ Field ที่เราใช้เข้าไป แทนที่จะกดทั้งหมดเลย แต่ตารางมันมี 2 ด้าน โดยเฉพาะด้าน Row นี่แหละ สนุก เพราะมันเพิ่มได้เยอะขึ้นเรื่อย ๆ เลย บาง Table อาจจะประกอบด้วยหลายล้าน Row ได้เลย

ถ้าเรา Query ขึ้นมาตรง ๆ เลย มันพยายามที่จะเอาทั้งหมดหลายล้านขึ้นมาเลยนะ แน่นอนว่า ใหญ่อลังการงานสร้างแน่นอน และ เอาจริง ๆ เราอาจจะไม่ได้ใช้เยอะขนาดนั้นด้วย ทำให้ถ้าเราอยากจะดูข้อมูลเฉย ๆ ก็ใส่ Limit ไว้ด้วยจะดีมาก หรือ ถ้าเราต้องการข้อมูลมา Process อะไรบ้างอย่าง เช่นการนับ การหาค่า Max, Min อะไรพวกนั้น เราก็สามารถทำใน SQL เลยก็ได้ อันนี้ขึ้นกับงาน และ การออกแบบของเราเลยนะ เราอาจจะยอม Query ทั้งหมดแล้วเอามา Process ใน Server ก็ได้ หรือ เราจะผลักภาระให้ Database Server จัดการไปก็ได้เหมือนกัน หรือ ถ้าเรารู้ว่า เรามีการ Query ข้อมูลพวกนี้เยอะ เราก็อาจจะทำ View ขึ้นมาไว้เลยก็ได้ หรือ เราจะหาวิธีการ Cache อะไรก็ว่ากันไป จะได้ง่าย ๆ

Read Next...

จัดการข้อมูลบน Pandas ยังไงให้เร็ว 1000x ด้วย Vectorisation

จัดการข้อมูลบน Pandas ยังไงให้เร็ว 1000x ด้วย Vectorisation

เวลาเราทำงานกับข้อมูลอย่าง Pandas DataFrame หนึ่งในงานที่เราเขียนลงไปให้มันทำคือ การ Apply Function เข้าไป ถ้าข้อมูลมีขนาดเล็ก มันไม่มีปัญหาเท่าไหร่ แต่ถ้าข้อมูลของเราใหญ่ มันอีกเรื่องเลย ถ้าเราจะเขียนให้เร็วที่สุด เราจะทำได้โดยวิธีใดบ้าง วันนี้เรามาดูกัน...

ปั่นความเร็ว Python Script เกือบ 700 เท่าด้วย JIT บน Numba

ปั่นความเร็ว Python Script เกือบ 700 เท่าด้วย JIT บน Numba

Python เป็นภาษาที่เราใช้งานกันเยอะมาก ๆ เพราะความยืดหยุ่นของมัน แต่ปัญหาของมันก็เกิดจากข้อดีของมันนี่แหละ ทำให้เมื่อเราต้องการ Performance แต่ถ้าเราจะบอกว่า เราสามารถทำได้ดีทั้งคู่เลยละ จะเป็นยังไง เราขอแนะนำ Numba ที่ใช้งาน JIT บอกเลยว่า เร็วขึ้นแบบ 700 เท่าตอนที่ทดลองกันเลย...

Humanise the Number in Python with "Humanize"

Humanise the Number in Python with "Humanize"

หลายวันก่อน เราทำงานแล้วเราต้องการทำงานกับตัวเลขเพื่อให้มันอ่านได้ง่ายขึ้น จะมานั่งเขียนเองก็เสียเวลา เลยไปนั่งหา Library มาใช้ จนไปเจอ Humanize วันนี้เลยจะเอามาเล่าให้อ่านกันว่า มันทำอะไรได้ แล้วมันล่นเวลาการทำงานของเราได้ยังไง...

ทำไม 0.3 + 0.6 ถึงได้ 0.8999999 กับปัญหา Floating Point Approximation

ทำไม 0.3 + 0.6 ถึงได้ 0.8999999 กับปัญหา Floating Point Approximation

การทำงานกับตัวเลขทศนิยมบนคอมพิวเตอร์มันมีความลับซ่อนอยู่ เราอาจจะเคยเจอเคสที่ เอา 0.3 + 0.6 แล้วมันได้ 0.899 ซ้ำไปเรื่อย ๆ ไม่ได้ 0.9 เพราะคอมพิวเตอร์ไม่ได้มองระบบทศนิยมเหมือนกับคนนั่นเอง บางตัวมันไม่สามารถเก็บได้ เลยจำเป็นจะต้องประมาณเอา เราเลยเรียกว่า Floating Point Approximation...