SQLite: เร็วกว่าระบบไฟล์ 35%
(sqlite.org)- 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 ความคิดเห็น
ถ้ารวมการเข้าถึงคุณสมบัติของไฟล์ในฐานข้อมูลด้วย (เช่น ชื่อไฟล์ ขนาด สิทธิ์การเข้าถึง ฯลฯ)
ไม่อย่างนั้นก็น่าจะต้องเปรียบเทียบกับ block I/O มากกว่า ไม่ใช่ file I/O หรือเปล่าครับ…
ไม่ว่าอย่างไหน SQLite ก็เร็วจริง ๆ นั่นแหละ
ความคิดเห็นบน Hacker News
เนื่องจากไม่มีแอตทริบิวต์หรือเมทาดาทาของระบบไฟล์ จึงไม่ต้องมีการบันทึกหรืออัปเดตแอตทริบิวต์เพิ่มเติม และไม่มีการตรวจสอบไฟล์จริงหรือ pipe/symbolic link, การตรวจสอบสิทธิ์, ความไม่ตรงกันของการจัดแนวขนาดบล็อก ฯลฯ จึงต้องใช้เพียงคำสั่งเปิดไฟล์ครั้งเดียว
rsyncเพื่อสำรวจและจัดการไฟล์ได้การเร็วขึ้น 4 เท่าบน Windows 10 เน้นให้เห็นว่าการเรียกระบบไฟล์ของ Windows ช้ามากแค่ไหน
มีไอเดียจะบันทึกโน้ตทั้งหมดที่ออกมาจากดิจิทัลเปียโนแบบเรียลไทม์
การเปรียบเทียบกับงานวิจัยด้าน OS จากมุมมองของห้องแล็บวิจัยฐานข้อมูลเป็นเรื่องน่าสนใจ
กำลังพิจารณาเพิ่มข้อมูลลงใน sqlite DB ในโหมด WAL2
ในฐานข้อมูล SQLite มีการเรียก system call
open()และclose()เพียงครั้งเดียวไม่แนะนำให้ใช้ฟิลด์ blob ของ SQLite เพื่อเก็บไฟล์
การที่สิ่งซึ่งสร้างอยู่บนระบบไฟล์กลับเร็วกว่าไฟล์ซิสเต็ม หมายความว่าระบบไฟล์จะช้าเมื่อถูกใช้งานในรูปแบบที่ไม่ได้ปรับให้เหมาะสม
การลบหลายแถวในฐานข้อมูล SQLite ช้ากว่าการลบไฟล์
การเข้าถึงระบบไฟล์/ไดรฟ์ทั้งหมดถูกจัดการโดย OS
เมื่อ 20 ปีก่อนเคยใช้งานสถาปัตยกรรมที่เก็บไฟล์เป็น blob ไว้ใน Oracle DB ได้ดีมาก แต่ต้องคอยอธิบายข้อดีของมันให้คนอื่นฟังทุกครั้ง... แน่นอนว่าไม่ได้สำเร็จทุกครั้งเสมอไป
ถ้าเป็นเมื่อ 20 ปีก่อน ราคา Oracle SAN DISK คงไม่ใช่ถูกๆ แน่..