15 คะแนน โดย GN⁺ 2024-07-28 | 4 ความคิดเห็น | แชร์ทาง WhatsApp
  • SQLite สามารถอ่านและเขียน Blob ขนาดเล็ก (เช่น รูปภาพ thumbnail) ได้เร็วกว่าการอ่านหรือเขียนด้วย fread() หรือ fwrite() จากไฟล์แยกเดี่ยวถึง 35%
  • นอกจากนี้ ฐานข้อมูล SQLite เดียวที่เก็บ Blob ขนาด 10KB ยังใช้พื้นที่ดิสก์น้อยกว่าการเก็บ Blob เป็นไฟล์แยกเดี่ยวประมาณ 20%
  • ความแตกต่างด้านประสิทธิภาพดูเหมือนจะเกิดจากการที่เมื่อทำงานกับฐานข้อมูล SQLite จะมีการเรียก system call open() และ close() เพียงครั้งเดียว ขณะที่การใช้ Blob ในไฟล์แยกเดี่ยวจะต้องเรียก open() และ close() หนึ่งครั้งต่อ Blob แต่ละรายการ จึงดูเหมือนว่า overhead ของ open() และ close() จะมากกว่า overhead ของการใช้ฐานข้อมูล
  • การลดขนาดเกิดขึ้นเพราะไฟล์แยกเดี่ยวจะถูกเติมให้เต็มถึงพหุคูณถัดไปของขนาดบล็อกของระบบไฟล์ ขณะที่ Blob ถูกบรรจุอย่างหนาแน่นกว่าในฐานข้อมูล SQLite

ข้อควรระวัง

  • ตัวเลข 35% เป็นเพียงค่าคร่าว ๆ เท่านั้น เวลาที่วัดจริงจะแตกต่างกันไปตามฮาร์ดแวร์ ระบบปฏิบัติการ และรายละเอียดของการทดลอง อีกทั้งยังมีความผันผวนของประสิทธิภาพแบบสุ่มบนฮาร์ดแวร์จริง
  • ตัวเลข 35% มาจากผลการทดสอบบนทุกระบบที่ผู้เขียนเข้าถึงได้ง่าย ผู้รีวิวบางรายรายงานว่าบนระบบของตน SQLite มี latency สูงกว่า direct I/O และยังไม่เข้าใจความแตกต่างนั้น
  • พบว่า SQLite ทำงานได้ไม่ดีเท่ากับ direct I/O เมื่่อรันการทดลองด้วย file system cache แบบเย็น
  • เอกสารนี้โต้แย้งสมมติฐานทั่วไปที่ว่าฐานข้อมูลเชิงสัมพันธ์ควรจะช้ากว่า file system I/O โดยตรง
  • งานวิจัยปี 2022 ระบุว่าในงานจริง SQLite เร็วกว่า Linux บน Btrfs และ Ext4 ประมาณ 2 เท่า

วิธีการวัด

  • ประสิทธิภาพ I/O ถูกวัดด้วยโปรแกรม kvtest.c ใน source tree ของ SQLite
  • เพื่อคอมไพล์โปรแกรมทดสอบนี้ ให้รวบรวมไฟล์ซอร์ส kvtest.c ไว้ในไดเรกทอรีเดียวกับไฟล์ซอร์ส amalgamation ของ SQLite คือ sqlite3.c และ sqlite3.h จากนั้นรันคำสั่งบน Unix ที่คล้ายกับต่อไปนี้
  • โปรแกรม kvtest ที่ได้จากคำสั่งนี้จะถูกใช้สร้างฐานข้อมูลทดสอบที่ประกอบด้วย Blob แบบสุ่มไม่บีบอัดจำนวน 100,000 รายการ โดยแต่ละ Blob มีขนาดระหว่าง 8,000 ถึง 12,000 ไบต์
  • สามารถรันคำสั่ง export พร้อมตัวเลือกบรรทัดคำสั่ง --tree เพื่อสร้างสำเนาของ Blob ทั้งหมดเป็นไฟล์แยกเดี่ยวในไดเรกทอรีได้
  • ใช้คำสั่งต่อไปนี้เพื่อวัดประสิทธิภาพการอ่าน Blob จากฐานข้อมูลและการอ่าน Blob จากไฟล์แยกเดี่ยว
  • ตัวเลือก --blob-api ทำให้ SQLite โหลดเนื้อหา Blob ด้วยฟังก์ชัน sqlite3_blob_read() แทนการรันคำสั่ง SQL จึงทำให้การทดสอบการอ่านเร็วขึ้นเล็กน้อย

การวัดประสิทธิภาพการอ่าน

  • บน Windows10 สามารถอ่านเนื้อหาจากฐานข้อมูล SQLite ได้เร็วกว่าการอ่านจากดิสก์โดยตรงประมาณ 5 เท่า
  • บน Android, SQLite เร็วกว่าการอ่านจากดิสก์ประมาณ 35%
  • เมื่ออ่านจากฐานข้อมูลที่ทำ memory mapping โดยใช้ sqlite3_blob_read() บน Mac และ Android จะเร็วกว่าอ่านไฟล์แยกเดี่ยวจากดิสก์ 2 เท่า และบน Windows เร็วกว่า 10 เท่า
โฆษณา

การวัดประสิทธิภาพการเขียน

  • ในทุกระบบ ทั้ง direct I/O และ SQLite มีประสิทธิภาพการเขียนช้ากว่าการอ่าน 5 ถึง 15 เท่า
  • ในการทดสอบการเขียน ซอฟต์แวร์แอนติไวรัสแทบไม่มีผลต่อการเขียนของ SQLite แต่ทำให้การเขียนลงดิสก์โดยตรงช้าลงประมาณ 10 เท่า
  • สาเหตุน่าจะเป็นเพราะ SQLite เปลี่ยนแปลงเพียงไฟล์ฐานข้อมูลไฟล์เดียว ขณะที่การเขียนลงดิสก์โดยตรงต้องเปลี่ยนไฟล์แยกเดี่ยวหลายพันไฟล์ซึ่งแอนติไวรัสต้องตรวจสอบ

ผลลัพธ์โดยทั่วไป

  • SQLite มีความสามารถในการแข่งขันกับ Blob ที่เก็บในไฟล์ดิสก์แยกเดี่ยวทั้งการอ่านและการเขียน และมักจะเร็วกว่า
  • SQLite เร็วกว่าการเขียนลงดิสก์โดยตรงอย่างมากบน Windows เมื่อเปิดใช้งานการป้องกันของแอนติไวรัส
  • การอ่านเร็วกว่าการเขียนประมาณ 10 เท่าในทุกระบบ และทั้งสำหรับ SQLite กับ direct disk I/O
  • ประสิทธิภาพ I/O แตกต่างกันอย่างมากตามระบบปฏิบัติการและฮาร์ดแวร์ จึงควรวัดผลด้วยตนเองก่อนสรุป
  • SQL database engine อื่นบางตัวแนะนำให้นักพัฒนาเก็บ Blob เป็นไฟล์แยกแล้วบันทึกชื่อไฟล์ไว้ในฐานข้อมูล แต่ในกรณีนี้ การเก็บ Blob ทั้งก้อนในฐานข้อมูลให้ประสิทธิภาพการอ่านและเขียนที่ดีกว่ามากใน SQLite

ความเห็นของ GN⁺

  • น่าสนใจมากที่ประสิทธิภาพของ SQLite ดีกว่าการอ่านและเขียนไฟล์แยกเดี่ยว ซึ่งน่าจะช่วยปรับปรุงประสิทธิภาพของแอปพลิเคชันที่ใช้ฐานข้อมูลได้
  • อย่างไรก็ตาม ผลเบนช์มาร์กนี้ไม่ได้ใช้ได้ทั่วไปกับทุกสถานการณ์ อาจแตกต่างกันตามลักษณะข้อมูล รูปแบบการเข้าถึง และการตั้งค่าฮาร์ดแวร์ สำหรับแอปพลิเคชันสำคัญ ควรทำเบนช์มาร์กด้วย workload จริง
  • นอกจากนี้ SQLite ยังมีข้อดีคือสามารถหลีกเลี่ยงการตรวจของแอนติไวรัสได้ ซึ่งจะมีประโยชน์อย่างยิ่งกับแอปพลิเคชันที่จัดการไฟล์ขนาดเล็กจำนวนมาก
  • ข้อเสียของ SQLite คือข้อมูลทั้งหมดถูกเก็บไว้ในไฟล์เดียว ดังนั้นหากไฟล์ฐานข้อมูลเสียหาย ข้อมูลทั้งหมดอาจสูญหายได้ จึงควรสำรองไฟล์ฐานข้อมูลเป็นประจำ

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

 
iolothebard 2024-07-28

ถ้ารวมการเข้าถึงคุณสมบัติของไฟล์ในฐานข้อมูลด้วย (เช่น ชื่อไฟล์ ขนาด สิทธิ์การเข้าถึง ฯลฯ)
ไม่อย่างนั้นก็น่าจะต้องเปรียบเทียบกับ block I/O มากกว่า ไม่ใช่ file I/O หรือเปล่าครับ…
ไม่ว่าอย่างไหน SQLite ก็เร็วจริง ๆ นั่นแหละ

 
GN⁺ 2024-07-28
ความคิดเห็นบน Hacker News
  • เนื่องจากไม่มีแอตทริบิวต์หรือเมทาดาทาของระบบไฟล์ จึงไม่ต้องมีการบันทึกหรืออัปเดตแอตทริบิวต์เพิ่มเติม และไม่มีการตรวจสอบไฟล์จริงหรือ pipe/symbolic link, การตรวจสอบสิทธิ์, ความไม่ตรงกันของการจัดแนวขนาดบล็อก ฯลฯ จึงต้องใช้เพียงคำสั่งเปิดไฟล์ครั้งเดียว

    • เข้าใจได้เมื่อยอมตัดฟังก์ชันบางอย่างออกและละเลยการออกแบบแบบอเนกประสงค์
    • หากใช้การแมปแบบ FUSE กับ SQLite แล้วเมานต์ไดเรกทอรีเพื่อเข้าถึง ประสิทธิภาพอาจใกล้เคียงกันหรือช้ากว่า
    • หากปิดการใช้แอตทริบิวต์และสร้างระบบไฟล์แบบคัสตอมด้วยขนาดบล็อกที่ปรับให้เหมาะสม ก็อาจได้ประสิทธิภาพใกล้เคียงกัน
    • มีความเรียบง่ายตรงที่สามารถใช้คำสั่งเชลล์อย่าง rsync เพื่อสำรวจและจัดการไฟล์ได้
    • SQLite เหมาะกับ static asset ที่แพ็กมาเป็นชุดหรือแอปพลิเคชันประเภท appliance
  • การเร็วขึ้น 4 เท่าบน Windows 10 เน้นให้เห็นว่าการเรียกระบบไฟล์ของ Windows ช้ามากแค่ไหน

  • มีไอเดียจะบันทึกโน้ตทั้งหมดที่ออกมาจากดิจิทัลเปียโนแบบเรียลไทม์

    • ใช้ SQLite เก็บเป็นตารางเดียว โดยแต่ละแถวคือเหตุการณ์ MIDI ของเปียโน
    • ประสิทธิภาพดีและยังนำไปวิเคราะห์ภายหลังได้
  • การเปรียบเทียบกับงานวิจัยด้าน OS จากมุมมองของห้องแล็บวิจัยฐานข้อมูลเป็นเรื่องน่าสนใจ

    • ฐานข้อมูลเชิงสัมพันธ์ถูกปรับให้เหมาะกับเรกคอร์ดขนาดเล็กแต่ละรายการและความสอดคล้องของข้อมูล
    • เมื่อขนาดของแถวใหญ่ขึ้น ประสิทธิภาพจะลดลงอย่างมาก
  • กำลังพิจารณาเพิ่มข้อมูลลงใน sqlite DB ในโหมด WAL2

    • แทบไม่มีค่าปรับด้านประสิทธิภาพการเขียน และมีข้อดีมากสำหรับการอ่าน/วิเคราะห์
  • ในฐานข้อมูล SQLite มีการเรียก system call open() และ close() เพียงครั้งเดียว

    • มี overhead น้อยกว่าการใช้ blob ในไฟล์แยกแต่ละไฟล์
  • ไม่แนะนำให้ใช้ฟิลด์ blob ของ SQLite เพื่อเก็บไฟล์

    • ขนาดสูงสุดของ blob คือ 2GB
    • ต้อง serialize/deserialize อ็อบเจ็กต์เป็นไบต์
    • หากต้องโต้ตอบกับระบบ/บริการอื่น ก็ยังต้องใช้ไฟล์
    • แม้ SQLite จะมีการตั้งค่าสำหรับจัดการคำขอแบบขนาน แต่คำขอที่แย่งกันจะทำให้ฐานข้อมูลถูกล็อก
  • การที่สิ่งซึ่งสร้างอยู่บนระบบไฟล์กลับเร็วกว่าไฟล์ซิสเต็ม หมายความว่าระบบไฟล์จะช้าเมื่อถูกใช้งานในรูปแบบที่ไม่ได้ปรับให้เหมาะสม

  • การลบหลายแถวในฐานข้อมูล SQLite ช้ากว่าการลบไฟล์

  • การเข้าถึงระบบไฟล์/ไดรฟ์ทั้งหมดถูกจัดการโดย OS

    • ไฟล์ฐานข้อมูลถูกเก็บเป็นคลัสเตอร์บนดิสก์
    • ระบบจัดการฐานข้อมูลถูกสร้างขึ้นเพื่อแก้ปัญหาเฉพาะโดเมนและทำให้ใช้งานได้สะดวก
 
halfenif 2024-07-28

เมื่อ 20 ปีก่อนเคยใช้งานสถาปัตยกรรมที่เก็บไฟล์เป็น blob ไว้ใน Oracle DB ได้ดีมาก แต่ต้องคอยอธิบายข้อดีของมันให้คนอื่นฟังทุกครั้ง... แน่นอนว่าไม่ได้สำเร็จทุกครั้งเสมอไป

 
narusas 2024-07-29

ถ้าเป็นเมื่อ 20 ปีก่อน ราคา Oracle SAN DISK คงไม่ใช่ถูกๆ แน่..