ข้าม​ไป​ยัง​เนื้อหา

column store จาก​ศูนย์ — เก็บ​กลับ​ด้าน​แล้ว​อ่าน​มากกว่า​เดิม

เก็บ​ตา​รา​งอ​อเด​อร์​ใบ​เดิม​ของ​เสา​นี้​กลับ​ด้าน แล้ว​ถาม​คำถาม​เดียว คือ​การ​วาง​ค่า​ของ column เดียวกัน​ไว้​ติด​กัน​ทำให้​อ่าน​น้อย​ลง​จริง​ไหม คำ​ตอบ​ที่​วัด​ได้​คือ​ยัง คลัง column ที่​ยัง​ไม่​เข้า​รหัส​และ​แตะ​ครบ 6 จาก 6 column แตะ 3320 หน้า ส่วน heap ที่​มัน​มา​แทน​แตะ 3153 หน้า เปิด bit packing บน​ข้อมูล​ชุด​เดิม​แล้ว​ทรง​เดียวกัน​เหลือ 989 หน้า ธี​สิ​ส​ของ​คอร์ส​จึง​เป็นการ​แยก​การ​วาง​แนว​ออก​จาก​การ​เข้า​รหัส ซึ่ง​เป็น​สอง​เรื่อง​ที่​สรุป​ตาม​ตำรา​รวม​ไว้​เป็น​ก้อน​เดียว และ​การ​รวม​นั้น​วัด​ได้​ว่า​ผิด
ความคืบหน้า0 / 8 บทเรียน

คำถาม​เดียว คำ​ตอบ​พลิก​สาม​ชั้น และ​ทั้ง​สาม​ชั้น​วัด​เป็น​จำนวนนับ

คำถาม​คือ การ​วาง​ค่า​ของ column เดียวกัน​ไว้​ติด​กัน ทำให้​อ่าน​น้อย​ลง​จริง​ไหม

ชั้น​ที่​หนึ่ง การ​วาง​แนว​อย่าง​เดียว​แพ้ คลัง column ที่​ยัง​ไม่​เข้า​รหัส​และ​แตะ​ครบ 6 จาก 6 column แตะ 3320 หน้า ส่วน heap ที่​มัน​มา​แทน​สแกน​ทั้ง​ตาราง​แตะ 3153 หน้า

เปิด bit packing บน​ข้อมูล​ชุด​เดิม แล้ว​ทรง​เดียวกัน​เหลือ 989 หน้า สิ่ง​ที่​เปลี่ยน ระหว่าง​สอง​ตัวเลข​นั้น​ไม่ใช่​การ​วาง​แนว เพราะ​มัน​วาง​แนว​เดียวกัน​ทั้ง​คู่ ที่​ชนะ​คือ​การ​เข้า​รหัส

ชั้น​ที่​สอง กลไก​ที่​ตำรา​ยก​ให้​คลัง column อยู่​ใน​คลัง​แนว​แถว​มา​ก่อน​แล้ว heap ของ​คอร์ส​ที่ 26 เก็บ status ทั้ง column ด้วย 200,000 ไบต์ เพราะ​มัน​แทน​สตริง​ด้วย​ตัว​รหัส​หนึ่ง byte มา​ตั้งแต่​ต้น ส่วน​คลัง column ที่​เก็บ​สตริง​ดิบ​ใช้ 1,985,792 ไบต์

การ​เทียบ heap กับ​คลัง column ที่​พบ​ทั่วไป​จึง​เทียบ​ของ​ที่​เข้า​รหัส​แล้ว กับ​ของ​ที่​ยัง​ไม่​เข้า​รหัส

ชั้น​ที่​สาม เมื่อ​แยก​สอง​เรื่อง​ออก​จาก​กัน ตัวเลข​ที่​ได้​ใหญ่​กว่า​ที่​ตำรา​สัญญา เลือก การ​เข้า​รหัส​ที่​เล็ก​ที่สุด​ต่อ column แล้ว​ทั้ง​คลัง​เหลือ 1,238,089 ไบต์ คิด​เป็น 305 หน้า เทียบ heap ที่ 12,914,688 ไบต์ และ 3153 หน้า

และ​ไม่มี​การ​เข้า​รหัส​ตัว​ไหน​ชนะ​ทุก column การ​เลือก​จึง​เป็น​งาน​ต่อ column ไม่ใช่​การ​ตั้ง​ค่า​ครั้ง​เดียว

ประกาศ​ไว้​ตรง​นี้ เพราะ​หน่วย​เป็น​สิ่ง​ที่​ตัดสิน​ว่า​ข้อ​อ้าง​ไหน​เข้า​คอร์ส​นี้​ได้

ทั้ง​คอร์ส​ไม่มี​หน่วย​เวลา​สัก​ตัว คอร์ส​นี้​รับ​กฎ​ข้อ​นี้​มา​ทั้ง​ดุ้น​จาก​คอร์ส​ที่ 26 ของ​เสา​เดียวกัน หน่วย​ที่​คอร์ส​นี้​ยอมรับ​มี​เจ็ด​อย่าง

  • จำนวน​หน้าที่​แตะ ซึ่ง​นับ​ด้วย Pager.reads ตัว​เดียว​กับ​คอร์ส​ที่ 26 ไม่ใช่​ตัว​นับ​ของ​ตัว​เอง
  • จำนวน​ไบต์​ที่​การ​เข้า​รหัส​หนึ่ง​แบบ​ใช้​เก็บ column หนึ่ง​ตัว
  • จำนวน row group ที่​ข้าม​ได้ ซึ่ง​นับ​จาก​การ​รัน​จริง ไม่ใช่​ค่า​ประมาณ
  • จำนวน​ค่าที่​ถอดรหัส ซึ่ง​เป็น​หน่วย​ที่​เคลื่อน​ไป​คนละ​ทาง​กับ​หน้าที่​แตะ​ได้
  • จำนวน​บิต​ต่อ​ค่า ซึ่ง​เป็น​ค่า​ต่อ row group ไม่ใช่​ค่า​ต่อ​ทั้ง column
  • จำนวน run คือ​ช่วง​ของ​ค่าที่​เหมือน​กัน​ติด​กัน
  • จำนวน​ค่าที่​ไม่​ซ้ำ ทั้ง​ของ​ทั้ง column และ​ของ​ภายใน row group เดียว

ความเร็ว​มี​นาฬิกา​อยู่​ข้าง​ใน คอร์ส​นี้​จึง​ไม่​วัด​มัน​และ​ไม่​พูด​ถึง​มัน

สนาม​แข่ง​เป็น​ตาราง​ใบ​เดิม​ของ​เสา​นี้ และ probe รัน​ได้​บน​เครื่อง​เปล่า

  • สนาม​แข่ง คือ​ตา​รา​งอ​อเด​อร์ 200,000 แถว จาก seed 20260802 ซึ่ง​ให้ md5(repr(rows)) เป็น 6796858c189960daa42506f5ed86d573 ทุก​ครั้ง · หน้า​ขนาด 4096 ไบต์ · row group ปริยาย 10,000 แถว จึง​ได้ 20 กลุ่ม
  • probe คือ scripts/column-store/probe.py ซึ่ง​ยืนยัน 65 ข้อ​อ้าง และ​รัน 3 รอบ ต่อ​การ​เรียก​หนึ่ง​ครั้ง แล้ว​แดง​ถ้า​มี​ค่า​ไหน​ขยับ​ระหว่าง​รอบ
  • ของ​ที่​ต้อง​มี​มี​อย่าง​เดียว​คือ Python 3 ไม่​ต้อง​มี Docker ไม่​ต้อง​ต่อ​เน็ต และ​ไม่​ต้อง​ติด​ตั้ง​อะไร​นอก standard library
  • ตาราง​ของ​คอร์ส​ที่ 26 และ 28 ถูก​ใช้​ซ้ำ ไม่​ได้​ถูก​แก้ probe นำ​เข้า fixture.py กับ heapfile.Pager จาก scripts/query-engine/qe/ และ​ไม่​แก้​อะไร​ที่​นั่น​แม้แต่ byte เดียว

ตัวเลข​ทุก​ตัว​ที่​บท​เรียน​พิมพ์​มี​คีย์​ของ​ตัว​เอง​อยู่​ใน scripts/column-store/expected/column-store.txt ซึ่ง​เป็น​ของ​ที่ --emit สร้าง​ขึ้น

zone map เป็นการ​ตัด​ทิ้ง ส่วน​การ​ประมาณ​จำนวน​แถว​เป็น​ของ​คอร์ส​ก่อน​หน้า

การ​ประมาณ​จำนวน​แถว histogram uniformity และ independence เป็น​เรื่อง​ของ คอร์ส​ที่ 26 บท​ที่ 4 ซึ่ง​มี​หัวข้อ​ของ​ตัว​เอง​ครบ​อยู่​แล้ว คอร์ส​นี้​ไม่​คำนวณ​และ​ไม่​รายงาน​ค่า​ประมาณ​ความ​เลือกสรร​สัก​ตัว

เส้น​แบ่ง​คือ zone map ตัด​ทั้ง row group ทิ้ง มัน​ไม่​ได้​เดา​ว่า​จะ​เจอ​กี่​แถว คอร์ส​นี้​จึง​รายงาน จำนวน​กลุ่ม​ที่​ข้าม​ได้​จริง​จาก​การ​รัน เช่น​เงื่อนไข​บน placed_at ข้าม​ได้ 19 จาก 20 กลุ่ม ส่วน​เงื่อนไข​บน customer ข้าม​ได้ 0 กลุ่ม

ตัวเลข 1,017 แถว กับ 995 แถว ใน​บท​ที่ 6 เป็น​จำนวน​แถว​ที่​ตรง​จริง​จาก​การ​นับ มัน​มี​ไว้ พิสูจน์​ว่า​สอง​คำถาม​นั้น​อยู่​ใน​ระดับ​เดียวกัน ไม่​ได้​มี​ไว้​ประมาณ​อะไร

ประกาศ​ไว้​ตรง​นี้ เพื่อ​ไม่​ให้​ใคร​อ่าน​จบ​แล้ว​เชื่อ​ว่า​ได้​ของ​ที่​คอร์ส​นี้​ไม่​ได้​ให้

  • ไม่​วัด​ความเร็ว ทั้ง​คอร์ส​ไม่มี​หน่วย​เวลา​สัก​ตัว เหมือน​คอร์ส​ที่ 26 และ 28 ใน​เสา​เดียวกัน
  • ไม่​แตะ vectorized execution และ SIMD เป็น​เหตุผล​ใหญ่​ข้อ​หนึ่ง​ของ​เอน​จิน​แนว column จริง แต่ probe ของ​คอร์ส​นี้​ไม่​ได้​วัด​มัน​สัก​ทรง และ​การ​วัด​มัน​ต้อง​ใช้​หน่วย​เวลา
  • ไม่​แตะ​การ​บีบ​อัด​ทั่วไป อย่าง Snappy gzip หรือ zstd ไม่มี​ตัว​ไหน​ถูก​วัด จึง​ไม่มี​ข้อ​อ้าง
  • ไม่ใช่ Parquet ORC หรือ Arrow ของ​จริง ทุก​ข้อ​อ้าง​ผูก​กับ​คลัง​ที่ colstore.py สร้าง​ขึ้น · Parquet ถูก​อ้าง​ใน​ฐานะ​รูป​แบบ​เท่านั้น ไม่ใช่​ใน​ฐานะ​ของ​ที่​วัด
  • ไม่​แตะ​การ​เขียน​และ​การ​อัปเดต​แถว probe เขียน​คลัง​ครั้ง​เดียว​แล้ว​วัด​การ​อ่าน
  • ไม่​แตะ transaction และ isolation เป็น​คำถาม​ของ​คอร์ส​ที่ 28 คนละ​คำถาม​กัน

ต้อง​อ่าน Python ออก ส่วน​ความ​รู้​เรื่อง​คลัง​แนว column ไม่​ต้อง​มี​มา​ก่อน​สัก​นิด

  • Python ระดับ​อ่าน​ออก​และ​รัน​เอง​ได้ ทุก​บท​เขียน​ด้วย Python 3 และ standard library ล้วน
  • SQL ระดับ​เขียน SELECT … WHERE เป็น พอ ไม่​ต้อง​รู้​เรื่อง tuning มา​ก่อน
  • ไม่​ต้อง​รู้จัก​คลัง​แนว column มา​ก่อน ทุก​โครงสร้าง​ถูก​สร้าง​ขึ้น​ใหม่​ตั้งแต่ byte แรก
  • ไม่​บังคับ​ว่า​ต้อง​อ่าน​คอร์ส​ที่ 26 มา​ก่อน แต่​ตัวเลข​ของ​สอง​คอร์ส​วาง​ทาบ​กัน​ได้ เพราะ​ใช้​ตาราง ใบ​เดียวกัน​และ​ตัว​นับ​หน้า​ตัว​เดียวกัน
  • ตัวเลข​ทุก​ตัว​รัน​เอง​ได้ ด้วย python3 scripts/column-store/probe.py โดย​ไม่​ต้องเต​รี​ยม อะไร​ก่อน และ​ไม่มี container ให้​เก็บ​กวาด​ทีหลัง

แผนผัง​นี้​เติม​ขึ้น​เอง​เมื่อ​บท​เรียน​ถูก​เพิ่ม​เข้า​มา