การเลือกใช้งาน Compression Encoding สำหรับข้อมูลแต่ละคอลัมน์ของ Amazon Redshift

Compression หรือการบีบอัดข้อมูลนั้นเป็นกระบวนการที่เกิดขึ้นในระดับคอลัมน์ (column) เพื่อจะลดขนาดของข้อมูลที่จะถูกเก็บไว้บน storage ซึ่งจะช่วยลดการอ่านข้อมูลจาก disk ลง ผลที่ตามมาอีกคือ ทำให้เรา query ข้อมูลได้เร็วขึ้นนั่นเอง

Redshift สามารถกำหนด encoding ให้กับคอลัมน์อัตโนมัติ ถ้าเราสร้าง table ขึ้นมาใหม่แล้วใช้คำสั่ง copy ข้อมูล ซึ่งทาง Amazon ก็แนะนำให้ใช้วิธีนี้นะครับ ^^

แต่ถ้าเราอยากกำหนดเอง เราจะต้องกำหนด encoding ตอนที่เราสร้าง table หรือตอนที่เราเพิ่มคอลัมน์ ไม่สามารถเปลี่ยน encoding ของคอลัมน์ได้นะ ^^ ถ้าต้องการจะเปลี่ยนผมจะใช้วิธีเพิ่มคอลัมน์เข้าไปด้วย encoding ที่ต้องการ แล้วค่อย copy ค่าจากคอลัมน์เดิมไป แล้วค่อย rename คอลัมน์

ตอนนี้ก็มี Compression Encoding อยู่ด้วยกันดังนี้ครับ

Raw Encoding ก็ตามชื่อเค้าเลยครับ ค่าที่เลือกเป็น raw encoding จะไม่ถูกบีบอัดข้อมูล ซึ่ง encoding ประเภพนี้ถูกใช้เป็นค่า default สำหรับคอลัมน์ที่ใช้เป็น sort key และคอลัมน์ที่มีชนิดข้อมูลเป็น BOOLEAN, REAL, DOUBLE PRECISION

AZ64 Encoding เป็น encoding ที่ทาง Amazon ออกแบบขึ้นมาด้วยอัตราส่วนการบีบอัดข้อมูลและมีประสิทธิภาพในการ query ข้อมูลที่สูง เหมาะสำหรับชนิดข้อมูลที่เป็น numeric, date และ time

Byte-Dictionary Encoding (BYTEDICT) จะสร้าง dictionary ขึ้นมาสำหรับข้อมูลของคอลัมน์ในแต่ละ block ที่มีค่าไม่ซ้ำกัน (unique values) ซึ่ง dictionary จะใช้พื้นที่ในการเก็บข้อมูล 1M ข้อมูลจะเก็บใน dictionary 256 ค่า ส่วนข้อมูลที่เกิน 256 จะถูกเก็บเป็น raw encoding ข้อจำกัดตรงนี้เองทำให้ bytedict เหมาะกับข้อมูลที่มีค่าที่ไม่ซ้ำกันที่ไม่เกิน 256 ค่าในคอลัมน์นั่นเอง

Delta Encoding เป็น encoding ที่เหมาะสำหรับชนิดข้อมูลที่เป็น datetime การเก็บข้อมูลของ delta encoding เป็นการเก็บค่าความแตกต่างของข้อมูลในลำดับก่อนหน้า แทนที่จะเป็นการเก็บข้อมูลตรงๆ

เช่น เรามีการเก็บข้อมูล integer (ใช้พื้นที่ 4 bytes) เรียงตั้งแต่ 1 ถึง 10 ค่าแรก (1) จะใช้พื้นที่เก็บ 5 bytes (ข้อมูล 4bytes และ flag อีก 1 byte) ค่าต่อๆ ไป (2 – 10) ใช้พื้นที่แค่ 1 byte ในการเก็บข้อมูล แต่ละแถวต่างกันแค่ 1 (2 – 1 = 1) ทำให้ลดพื้นที่ในการเก็บข้อมูล 1 ถึง 10 จาก 40 bytes (10 x 4bytes) เหลือ 14 bytes (5 bytes + 9 bytes)

ถ้าค่าความแตกต่างของข้อมูลใหญ่เกินกว่าที่จะเก็บใน 1 bytes (DELTA) หรือ 2 bytes (DELTA32K) ข้อมูลจะถูกเก็บเป็น raw data รวมกับ flag อีก 1 byte

LZO Encoding เป็น encoding ที่มีอัตราส่วนการบีบอัดข้อมูลและประสิทธิภาพที่สูง เหมาะกับชนิดข้อมูลที่เป็น VARCHAR หรือ CHAR ที่เป็นการเก็บข้อมูลเยอะๆ ยาวๆ เช่น คำอธิบายสินค้า ความคิดเห็น หรือ json string

Mostly Encoding เป็น encoding ที่เราต้องดูข้อมูลที่เราเก็บก่อนว่าค่าที่เก็บกับชนิดข้อมูลที่ใช้เกินความจำเป็นไปรึป่าว ซึ่งมีให้เราเลือกใช้ MOSTLY8 (1byte), MOSTLY16 (2bytes) และ MOSTLY32 (4bytes) เช่น เราอาจจะมีคอลัมน์ CATEGORY_ID ที่เป็น INTEGER (4 bytes) แต่ค่าที่เก็บยังมีแค่ 0 ถึง 300 เราสามารถใช้ MOSTLY16 ซึ่งใช้พื้นที่ในการเก็บน้อยกว่า 2 bytes

Runlength Encoding มีการสร้าง dictionary เก็บข้อมูลที่เก็บซ้ำๆ กันในแต่ละช่วงแถว ทำให้ไม่ต้องเก็บข้อมูลในแถวที่ซ้ำกันเยอะ แต่แนะนำว่าไม่ควรนำไปใช้กับคอลัมน์ที่เป็น sort key

Text255 and Text32k Encodings เป็น encoding ที่เหมาะกับชนิดข้อมูลที่เป็น VARCHAR และมีคำที่ซ้ำๆ ในข้อมูล โดยจะสร้าง dictionary เก็บข้อมูลที่มีค่าไม่ซ้ำกัน ​(unique values) 245 คำแรกในคอลัมน์ ส่วนคำที่ไม่มีใน dictionary ก็จะถูกเก็บเป็น raw data ตัวอย่าง address อาจจะมีคำว่า province, district, street เก็บอยู่ซ้ำๆ ในคอลัมน์นี้ ทำให้เราลดพื้นที่เหลือแค่ 1 byte ในการเก็บข้อมูลของแต่ละคำ แทนที่จะเป็น 8bytes=province, 8bytes=district และ 6bytes=street

Zstandard Encoding (ZSTD) เป็น encoding ที่มีอัตราส่วนการบีบอัดที่สูงและมีประสิทธิภาพสูง โดยเฉพาะเมื่อใช้กับข้อมูล VARCHAR หรือ CHAR ที่มีขนาดของข้อมูลที่หลากหลาย หรือพูดอย่างง่ายๆ ก็คือยาวก็ยาวมากสั้นก็สั้นมาก ประมาณนี้

ถ้าเราต้องการจะเช็คว่า encoding ที่เราใช้อยู่นั้นเหมาะสมหรือเปล่า เราสามารถใช้คำสั่ง ANALYZE COMPRESSION ดูได้นะครับ จะได้รู้ว่าเราเลือกได้ถูกรึป่าว

ขอให้สนุกกับการทำงานกับข้อมูลครับ ^^