22 คะแนน โดย xguru 2024-05-22 | 3 ความคิดเห็น | แชร์ทาง WhatsApp
  • Mattermost ใช้ Elasticsearch เพื่อลดภาระของฐานข้อมูลและให้ผลการค้นหาที่เร็วขึ้นมาก
    • เพื่อให้ Elasticsearch ทำงานได้อย่างเหมาะสม จำเป็นต้องทำดัชนีข้อมูลทั้งหมดที่เป็นเป้าหมายการค้นหา
    • สำหรับข้อมูลที่ทำดัชนีไปแล้ว การทำดัชนีโพสต์และไฟล์ใหม่ในภายหลังค่อนข้างเร็ว
    • แต่การทำดัชนีฐานข้อมูลขนาดใหญ่มาก (โพสต์ 100 ล้านรายการ) ใหม่ทั้งหมดตั้งแต่ต้นนั้นช้ามาก (ผ่านไป 18 ชั่วโมงยังทำได้ไม่ถึงครึ่ง และยิ่งช้าลงเรื่อยๆ)
  • จากกราฟเวลาที่ใช้ต่อการเรียกฐานข้อมูลแต่ละครั้ง พบว่า SQL query ของเมธอด PostStore.GetPostsBatchForIndexing เป็นปัญหา
    • คิวรีนี้โดยพื้นฐานจะเรียงโพสต์ตาม creation timestamp และคืนค่าโพสต์ใหม่กว่า timestamp ที่กำหนดจำนวน N รายการ
    • งาน indexing จะรันคิวรีนี้ซ้ำไปเรื่อยๆ จนกว่าโพสต์ทั้งหมดจะถูกทำดัชนี
  • ใช้ EXPLAIN (ANALYZE, BUFFERS) เพื่อวิเคราะห์ execution plan ของคิวรี:
    • ระหว่างการทำ index scan บนตาราง Posts มีการประมวลผล 40 ล้านบล็อกเพื่อใช้เงื่อนไข Filter (309GB)
    • การ JOIN กับตาราง Channels ไม่ใช่ปัญหา
    • ในเงื่อนไข OR ของ WHERE หากใช้เฉพาะส่วน Posts.CreateAt > ?1 จะเร็วขึ้นมาก (30ms)
    • จากนั้นเมื่อใช้เงื่อนไข Posts.CreateAt = ?1 AND Posts.Id > ?2 จะเร็วอย่างมากเป็นพิเศษ (0.047ms)
  • การหาสาเหตุ:
    • คิวรีต้นฉบับสแกนทุกแถวของ Posts แล้วค่อยกรองด้วย Filter ขณะที่คิวรีที่แก้ไขแล้วตรวจเฉพาะดัชนีและดึงเฉพาะแถวที่ต้องใช้
    • สาเหตุที่คิวรีช้าลงเรื่อยๆ ตามเวลาคือมีจำนวนแถวที่ต้องกรองทิ้งเพิ่มขึ้นเรื่อยๆ
  • วิธีแก้ไข:
    • ใช้ความสามารถ row constructor comparison ของ PostgreSQL โดยเปลี่ยนเงื่อนไขเป็น (Posts.CreateAt, Posts.Id) > (?1, ?2)
    • หลังเปลี่ยนแล้ว คิวรีนี้ลดเวลารันลงอย่างมากเหลือ 34 มิลลิวินาที
    • แต่ใน MySQL คิวรีที่เปลี่ยนกลับทำงานช้ากว่าเดิม ตรงกันข้าม MySQL ทำงานได้เร็วกว่าด้วยคิวรีต้นฉบับ จึงแยกโค้ดให้ใช้คิวรีต่างกันตามฐานข้อมูล
  • สิ่งที่ได้เรียนรู้:
    • เวลาใช้ EXPLAIN ควรใส่ตัวเลือก BUFFERS เสมอ
    • ควรทำให้ใช้ Index Cond แทน Filter
    • ควรตั้งต้นไว้เสมอว่า PostgreSQL และ MySQL ทำงานต่างกันเกือบทุกครั้ง
  • สรุป
    • การปรับแต่งครั้งนี้ช่วยลดเวลารันคิวรีได้มากกว่า 1000 เท่า
    • การปรับแต่งนี้ถูกรวมอยู่ใน Mattermost v9.7.0 และ v9.5 ESR
    • การปรับแต่งครั้งนี้ทำให้ได้เรียนรู้อะไรมากมาย

3 ความคิดเห็น

 
dontcryme 2024-05-23

อย่างที่มีเขียนไว้ในย่อหน้าสุดท้าย ชื่อบทความนี้ก็ให้ความรู้สึกเหมือนพาดหัวล่อคลิกนิดหน่อย...ถ้าจะปรับให้สื่อความจริงมากขึ้น

ก็คงเป็น

'กรณีศึกษาการใช้งาน PostgreSQL ที่ได้เรียนรู้ผ่านความผิดพลาด'

ละมัง..

 
vwjdalsgkv 2024-05-23

อืม... โดยส่วนตัวแล้ว ถ้าเขียนบทความระดับนี้โดยพาดพิงบริษัท/ผลิตภัณฑ์ใดผลิตภัณฑ์หนึ่ง ผมกลับรู้สึกว่าความน่าเชื่อถือต่อผลิตภัณฑ์นั้นจะลดลงไปมากเสียมากกว่า
การเรียบเรียงทำได้ชัดเจนเป็นลำดับดี แต่ก็น่าเสียดายที่คุณค่าทางเทคนิคที่อยู่ข้างในดูจะยังขาดไปสักหน่อย

 
savvykang 2024-05-23

หลังจากผมอ่านบทความนี้แล้วกลับยิ่งเชื่อถือน้อยลงไปอีก เพราะนี่หมายความว่าสินค้าที่รับเงินขายกันอยู่ได้ปล่อยฟีเจอร์ออกมาโดยไม่ได้ทดสอบการรองรับข้อมูลปริมาณมากเลย ดัชนีที่เรียบง่ายระดับนั้นน่าจะต้องตั้งไว้ตั้งแต่ขั้นตอนพัฒนาฟีเจอร์ไม่ใช่หรือ ผมรู้สึกว่ามีการข้ามขั้นตอนการพัฒนาซอฟต์แวร์ไปหลายอย่าง