เมื่อพูดถึง Index ในโลกของ Relational Database วิศวกรส่วนใหญ่มักจะนึกถึง B-Tree เป็นค่าเริ่มต้น ซึ่ง B-Tree ทำงานได้ไร้ที่ติกับการเปรียบเทียบค่าเชิงเส้นตรงทั่วไป เช่น การหาค่าที่เท่ากัน (=), การจัดเรียง (ORDER BY), หรือการหาช่วงของข้อมูลเดี่ยว (<, >, BETWEEN)
ทว่า เมื่อข้อมูลเริ่มมีความซับซ้อนมากกว่าค่าสเกลาร์ตัวเดียว เช่น พิกัดภูมิศาสตร์ (GIS), ช่วงเวลาที่มีจุดเริ่มและจุดจบ (Date Ranges), หรือ วัตถุที่มีขอบเขตซ้อนทับกัน (Bounding Boxes) ดัชนีแบบ B-Tree มักจะเจอทางตันทางสถาปัตยกรรม
PostgreSQL จึงออกแบบและสนับสนุนโครงสร้างดัชนีพิเศษขึ้นมาอย่างเป็นระบบ ซึ่งหนึ่งในตัวที่ทรงพลังที่สุดคือ GiST Index
GiST คืออะไร?
GiST ย่อมาจาก Generalized Search Tree มันไม่ได้เป็นโครงสร้างต้นไม้แบบตายตัวเพียงชนิดเดียว แต่เป็น “เทมเพลตสถาปัตยกรรมต้นไม้ค้นหา (Indexing Framework)” ที่เปิดให้ตัวระบบสามารถสร้าง Index บนโครงสร้างข้อมูลประเภทใดก็ได้ ตราบใดที่ข้อมูลนั้นมีตรรกะในการจับกลุ่มและหาความสัมพันธ์ระหว่างกัน
GiST ถูกพัฒนาขึ้นโดยคณะวิจัยจากมหาวิทยาลัย UC Berkeley ในช่วงทศวรรษ 1990 จุดเด่นคือการนำแนวคิดแบบสมดุลต้นไม้ (Balanced Tree) มาประยุกต์ใช้กับข้อมูลเชิงพื้นที่และเซต ทำให้ PostgreSQL สามารถใช้อัลกอริทึมต้นไม้เช่น R-Tree เพื่อจัดการข้อมูลหลายมิติได้อย่างยืดหยุ่น
หลักการทำงานเบื้องหลัง: จากเส้นตรงสู่ “Bounding Box”
ความแตกต่างพื้นฐานระหว่าง B-Tree กับ GiST อยู่ที่วิธีที่มันมองและจัดระเบียบข้อมูล
- B-Tree (1 มิติ)
ข้อมูลจะถูกจัดเรียงตามลำดับจากน้อยไปมากเป็นเส้นตรง กิ่งแม่จะบอกช่วงตัวเลข เช่น “โหนดนี้เก็บค่าระหว่าง 10 ถึง 20” จึงค้นหาได้มีประสิทธิภาพเฉพาะแกนเดียว - GiST (หลายมิติ)
โหนดแม่จะเก็บ “ขอบเขตครอบคลุม” (Bounding Predicate หรือ Bounding Box) ที่โอบล้อมข้อมูลของกิ่งลูกทั้งหมดเอาไว้
SQL
[ Root: Bounding Box ครอบคลุมพื้นที่/ช่วงเวลาทั้งหมด ]
/ \
[ Child A: กล่องครอบคลุม โซน 1 ] [ Child B: กล่องครอบคลุม โซน 2 ]
/ \ / \
[ ข้อมูล A1 ] [ ข้อมูล A2 ] [ ข้อมูล B1 ] [ ข้อมูล B2 ]