小巧。快速。可靠。
三者选其二。

SQLite 中的内部 BLOB 与外部 BLOB

如果您有一个包含大型 BLOB 的数据库,当您将完整的 BLOB 内容直接存储在数据库中时,是否可以获得更好的读取性能?或者将每个 BLOB 存储在单独的文件中,并在数据库中仅存储相应的文件名会更快?

为了尝试回答这个问题,我们在 Linux 工作站(大约 2011 年的 Ubuntu,在快速的 SATA 磁盘上使用 Ext4 文件系统)上运行了 49 个测试用例,这些用例使用了各种 BLOB 大小和 SQLite 页面大小。对于每个测试用例,都会创建一个包含 100MB BLOB 内容的数据库。BLOB 的大小范围从 10KB 到 1MB。BLOB 的数量有所不同,以使总的 BLOB 内容保持在约 100MB。(因此,对于 1MB 大小使用 100 个 BLOB,对于 10K 大小使用 10000 个 BLOB,依此类推。)使用了 SQLite 版本 3.7.8(2011 年 9 月 19 日)。

更新:SQLite 版本 3.19.0(2017 年 5 月 22 日)的新测量结果表明,对于 10KB blob 的读写,SQLite 比直接磁盘 I/O 快约 35%

下面的矩阵显示了读取存储在单独文件中的 BLOB 所需的时间除以读取完全存储在数据库中的 BLOB 所需的时间。因此,对于大于 1.0 的数字,将 BLOB 直接存储在数据库中更快。对于小于 1.0 的数字,将 BLOB 存储在单独的文件中更快。

在每种情况下,都会调整页面缓存大小,以使缓存内存量保持在约 2MB。例如,对于 1024 字节的页面,使用 2000 页缓存,对于 65536 字节的页面,使用 31 页缓存。BLOB 值以随机顺序读取。

数据库页面大小BLOB 大小
10k20k50k100k200k500k1m
10241.5351.0200.6080.4560.3300.2470.233
20482.0041.4370.8700.6360.4830.3720.340
40962.2611.8861.1730.8900.7010.5260.487
81922.2401.8661.3341.0350.8300.6250.720
163842.4391.7571.2921.0230.8290.8200.598
327681.8781.8431.2960.9810.9760.6750.613
655361.2561.2551.3390.9830.7690.6870.609

我们从上面的矩阵中推导出以下经验规则

当然,您的实际情况可能会因硬件、文件系统和操作系统而异。在确定特定设计之前,请在目标硬件上仔细检查这些数据。