如何更改mysql表的物理顺序?

时间:2014-04-07 07:42:46

标签: mysql database io

我正在尝试了解使用预定义顺序排列数据的正确方法,使用此示例可能更容易解释:

假设有一个带有userid列的表格帖子,它会被填充,因为帖子是使用autoincrement primary id发送的。应用程序需要从单个用户获取最后300个帖子,聚合它们并显示结果。如果有很多用户和帖子,可能会发生这个用户的所有300个帖子都在磁盘的不同位置,没有足够的ram来缓存数据库文件,并且要提供一个请求,mysql需要做300个操作,因此,如果硬盘能够完成150个iops,那个请求需要2秒钟,而第二个并发用户需要等待很多。

如果我的理解是正确的,那么用userid命令的表会使数据放在磁盘附近并且mysql能够读取1-ish io请求中的所有数据,从而使性能大大提高?那么如果我知道如何提前使用这些数据,如何让mysql以预定义的物理顺序放置行?一般来说这个问题是如何解决的?

我想继续使用自动增量,因为有其他可写的mysql服务器,并且使用自动增量偏移和增量很方便。

1 个答案:

答案 0 :(得分:3)

首先,一些理论上的局限性:

想象一下,数据是物理排序的。现在,如果用户发布另一条消息/评论会发生什么?为了保持订购,它必须在他的帖子旁边。这意味着要么

  • 你必须转移它旁边的所有帖子 - 不可能,因为你的问题明确假设有批次数据
  • 你需要文件中的洞以允许插入 - 但你应该保留多少空间?你不能提前知道。
  • 你把它存放在“chuncks”中。你为每个用户分配了几个磁盘块,一旦它被填满,你就分配一个新的块。现在你只需要寻找块而不是每个帖子。这种方法不会改变磁盘搜索的渐近复杂性,但将其降低到1/10或1/100仍然是一个巨大的胜利。不确定是否有任何RDBM这样做。
  • 您将它存储在其他地方,然后您修复了排序 - 基本上您正在进行磁盘碎片整理。理想情况下,RDBM会为您做到这一点 - 但实际上大多数都不会。您可以在每日(?)批处理过程中手动执行此操作,但这是一项非常复杂的任务(正确执行),因此,除非您在一家有能力执行此操作的大公司中,否则这是不可行的。

为了使情况变得更糟,正如@ D.Kasipovic在评论中提到的那样,你甚至不知道MySQL文件存储在物理磁盘上的哪个位置。它可能已经碎片化了。一些RDBM系统允许直接访问磁盘(我听说Oracle和SQL Server可以这样做),但我不知道它们是否支持记录的物理排序。

那你能做什么?

  • 使用SSD。它并不寻求它可以做很多的iops。问题解决了。
  • 如果您进行分片,请按用户分片。您只会使用查询强调单个数据库服务器(或其从属服务器)。
  • 如果您知道每个用户的帖子数量有一个合理的限制,您可以将用户的所有帖子存储在一行中。显然,这对于RDBM来说是一个相当丑陋的黑客攻击,但是使用一些noSQL解决方案它可以完成这项任务。

注意:我使用了所有这些方法(有时甚至在同一系统上)并且它们运行良好。如果您需要快速解决方案,SSD是一个轻松的胜利 - 请记住,除非您扩大规模,硬件比开发人员的工资便宜。