大型主键:超过10亿行MySQL + InnoDB?

时间:2008-12-13 16:18:13

标签: mysql indexing twitter large-data-volumes

我想知道InnoDB是否是格式化表格的最佳方式?该表包含一个字段,主键,该表每天将获得816k行(est。)。这将变得非常快!我正在研究文件存储方式(这会更快)吗?该表将存储已经处理过的Twitter ID的ID号?

此外,SELECT min('id')语句中估计的内存使用量是多少?非常感谢任何其他想法!

7 个答案:

答案 0 :(得分:6)

我建议你按照ID或日期开始partioning你的桌子。分区根据一些定义的逻辑将大表拆分成几个较小的表(比如按日期范围拆分),这使得它们更易于管理性能和内存。 MySQL 5.1内置了此功能,或者您可以使用自定义解决方案实现它。

在平面文件中实现存储时,您将失去数据库的所有优点 - 您无法再执行涉及数据的查询。

答案 1 :(得分:2)

唯一明确的答案是尝试两者并测试并看看会发生什么。

通常,MyISAM的写入和读取速度更快,但不能同时进行。当您写入MyISAM表时,整个表都会被锁定以完成插入。 InnoDB有更多的开销,但使用行级锁定,因此读取和写入可以同时发生,而不会出现MyISAM的表锁定问题。

但是,如果我理解正确,你的问题会有所不同。只有一列,该列作为主键,以MyISAM和InnoDB处理主键索引的不同方式有一个重要的考虑因素。

在MyISAM中,主键索引与任何其他二级索引一样。在内部,每行都有一个行id,索引节点只指向数据页的行ID。主键索引的处理方式与其他索引的处理方式不同。

然而,在InnoDB中,主键是群集的,这意味着它们保持与数据页的连接,并确保行内容按照主键保持在磁盘上的物理排序顺序(但仅限于单个数据页,它们本身可以按任何顺序分散。)

在这种情况下,我希望InnoDB可能有一个优势,即MyISAM基本上必须做双重工作 - 在数据页中写一次整数,然后在索引页中再次写入。 InnoDB不会这样做,主键索引与数据页相同,只需要写一次。它只需要在一个地方管理数据,MyISAM将不必要地管理两个副本。

对于任一存储引擎,执行像min()或max()这样的操作在索引列上应该是微不足道的,或者只是检查索引中是否存在数字。由于该表只有一列,因此不需要书签查找,因为数据完全在索引本身内表示。这应该是一个非常有效的指数。

我也不会担心桌子的大小。如果行的宽度只有一个整数,则每个索引/数据页面可以容纳大量的行。

答案 2 :(得分:1)

如果这些ID号单调增加并且您的写入仅附加数据(从不修改它),则使用单个文件可能要快得多。然后SELECT min('id')只是读取文件的第一行,而其他任何东西都是二进制搜索。

答案 3 :(得分:0)

如果你的id列上有一个索引,那么选择min(id)应该是O(1),对此应该没有太大的内存要求。

如果你的主键在twitter id上,那么你就有一个索引。

答案 4 :(得分:0)

MySQL Dev区域上的存储引擎有很好的比较:

从你的描述中我会说MyISAM会更好,但它在很大程度上依赖于你的应用程序的阅读和书写模式。

答案 5 :(得分:0)

使用一个单独的字段作为主键,只添加记录,这不适合常规数据库。

首先,您需要存储两倍的信息,每个字段都会进入数据表和索引。

顺便说一句,关系数据库是这样称呼的,因为它们将相关数据存储到一行中;很难看出你的数据如何合格:-)如果你也存储其他东西,那么数据库是值得的。

您没有提到数据是否会被多个进程同时访问 - 如果没有,那么您不需要数据库ACID原则赋予的所有优势。即使您确实需要ACID,仍然可以在没有完整数据库的情况下实现。

我的第一个是构建您自己的B树或B + -tree数据文件来存储twitter ID以避免数据重复。我能看到你做的唯一查询(根据问题)是:

  • 从tbl中选择min(id);和
  • 从tbl中选择ID,其中id =?

第一个可以通过简单地将最低层存储在B树结构之外的另一个文件中来制作O(1)(当你得到一个较低的文件时替换它)。我不确定这个商业案例,除非快速找到某个特定的推特ID不在表格中(所以你可能在这种情况下也想要最大)。

第二种是标准树搜索技术,无论如何,这是数据库通常使用的技术。

答案 6 :(得分:0)

我也看到一些交易公司使用tick数据库即。 KDB + http://kx.com/