【问题标题】:MySQL: Efficient Blobbing?MySQL:高效的 Blob?
【发布时间】:2011-01-09 08:46:49
【问题描述】:

我正在处理最多 - 我估计 - 大约 100 KB 的 blob 尺寸。数据已经压缩了。

存储引擎:MySQL 5.1 上的 InnoDB

前端:PHP(带有 Propel ORM 的 Symfony)

一些问题:

  • 我在某处读到过更新 blob 不好,因为 它会导致重新分配、碎片化,因此很糟糕 表现。真的吗?有这方面的参考吗?

  • 最初,blob 是通过附加数据块来构造的。每个 块的大小最大为 16 千字节。使用a是否更有效 而是单独的块表,例如具有如下字段?

    parent_id, position, chunk

    然后,要获取整个 blob,可以执行以下操作:

    SELECT GROUP_CONCAT(chunk ORDER BY position) FROM chunks WHERE parent_id = 187

    结果将用于 PHP 脚本。

  • blob 的类型之间是否有任何区别,除了 元数据所需的大小,应该可以忽略不计。

【问题讨论】:

  • GROUP_CONCAT() 不适合这个。默认情况下,它的最大长度限制为 1024 字节(尽管您可以使用 group_concat_max_len 进行更改)。您还必须非常小心地构建查询 - 如果块以错误的顺序分组/连接会发生什么?
  • 我认为限制没有问题,因为它可以扩展。关于以正确的顺序进行连接:这就是我提出position 字段的原因。这还不够吗?
  • 只需选择每个块并在 PHP 中连接它们。或者,如果您要输出它们,则输出它们而不连接它们。
  • araqnid:我为什么要这样做?有什么好处?事实上,我假设 MySQL 在这一步上效率更高。顺便说一句,然后对连接的结果进行后处理。它不会发送到屏幕上。

标签: php sql mysql performance propel


【解决方案1】:

如果您在表中创建和删除数据,您将获得表数据结构的碎片。

我不认为你可以通过将 blob 拆分成块来获得任何收益——在 DB 对数据进行分片之前将数据分片不会获得任何收益 :)

您可以通过重建表的结构来对其结构进行碎片整理(在 MySQL 中为OPTIMIZE TABLE)。

我找不到 MySQL 如何在磁盘上存储 blob 的信息。如果它将它们与其他行数据一起存储,那么您可以使用聚集索引(InnoDB 中的 PK,MyISAM 中的ALTER TABLE ORDER BY)来要求表的数据文件中的特定数据顺序(例如,按受欢迎程度排序以创建“热”区域,这可能会改善缓存并减少搜索)。

除了数据库自身结构的碎片外,文件系统中还存在表文件的碎片问题。

即使你只是将数据插入到表中,表本身的碎片为零,保存表文件的文件系统迟早会在磁盘上对其进行碎片化。这在安全文件系统上是不可避免的,因为它们从不就地更新文件数据。

如果 碎片是一个问题,那么我会尽可能在最低级别对其进行攻击。不要在数据库中存储 blob,只在磁盘上存储一些对文件的引用。

文件系统更接近物理磁盘,因此它们可以比数据库查询更好地处理碎片,数据库查询在它之上只有几个抽象级别。一些文件系统会自动对 文件进行碎片整理,但会留下大文件碎片。

或者您可能只是将硬件放在问题上 — 使用 RAID、为磁盘/数据库缓存添加大量 RAM 或使用 SSD。

当然,您已经仔细地对其进行了基准测试,并且知道碎片化首先是一个问题,对吧?

【讨论】:

  • 事实上,我发现 - 到目前为止 - 碎片不是问题。引入压缩后,blob 通常非常小(最多几千字节),并且附加操作很少见。因此,优先事项发生了一些变化。但是,我仍然对 blob 数据类型之间的区别感兴趣。另外,我记得读过 MySQL 将大 blob 存储在与小 blob 不同的位置,而且效率要低得多。这将是使用单独的块表的另一个原因,除了 - 是的 - 碎片。不过目前还不是问题。
猜你喜欢
  • 2011-10-08
  • 1970-01-01
  • 2011-09-03
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
  • 1970-01-01
  • 2018-10-10
  • 2017-07-23
相关资源
最近更新 更多