如何使用innodb

时间:2018-05-15 00:36:43

标签: mysql innodb full-table-scan

简介:有没有办法提高InnoDB表上的表扫描性能?

请不要建议为避免表扫描添加索引。 (见下文)

innodb_buffer_pool_size占服务器内存的75%(48 GB / 64GB) 我使用最新版本的Percona(5.7.19)如果改变了什么

更长:我们有600Gb的近期时间序列数据(我们汇总和删除旧数据)分布在50-60个表中。所以大部分都是"活跃"定期查询的数据。这些表有点大(400多个数字列),并且许多查询针对许多列运行(警报),这就是为什么添加索引是不切实际的(因为我们必须添加几十个)。最大的表每天都是分区的。

我完全清楚这是一个应用程序/表设计问题而不是服务器调优"问题。我们目前正在努力显着改变这些表的设计和查询方式,但必须维持现有系统,直到发生这种情况,所以我正在寻找一种方法来改善一些东西,以便我们花一点时间购买。

我们最近拆分了这个系统并将其中的一部分移到了新服务器上。它之前使用过MyISAM,我们尝试转移到TokuDB,这似乎是合适的,但遇到了一些奇怪的问题。我们切换到InnoDB,但性能非常糟糕。我得到的结论是MyISAM在桌面扫描方面表现更好,这就是为什么除非有更好的选择,否则我们会在新系统到位之前再回过头来。

更新

所有表格都具有相同的结构: -timestamp -primary key(varchar(20)field) - 各种类型的15个字段,表示可以过滤的其他辅助属性(以及首先适当的索引标准) - 然后大约几百个措施(花车),在200-400之间。

我已尽可能多地修剪行长而不改变结构本身。主键曾经是varchar(100),所有度量都是双倍的,许多次要属性的数据类型都发生了变化。

升级硬件不是一个真正的选择。

只使用我需要的列集创建小表将有助于某些进程执行得更快。但是以首先使用表扫描创建该表并复制数据为代价。也许如果我把它创建为内存表。根据我的估计,距离缓冲池只需几GB。此外,还有聚合过程可以定期从主表中读取尽可能多的数据,并且它们需要所有列。

遗憾的是,我打算在下一版本中解决这些问题中的大量重复工作。警报和汇总过程基本上每次插入一些行(每半小时)重新处理整天的数据,而不是仅处理新的/更改的数据。

就像我说的那样,较大的表是分区的,所以它通常是扫描每日分区而不是整个表,这是一个小小的安慰。

实现一个系统将其保存在数据库之外的内存中可能会有效,但这将需要对遗留系统和开发工作进行大量更改。不妨把时间花在更好的设计上。

InnoDB表对于与MyISAM相同的数据而言要大得多(在我的情况下是2-3倍),这实际上阻碍了性能。

2 个答案:

答案 0 :(得分:1)

MyISAM在表扫描方面稍微好一些,因为它比InnoDB更紧凑地存储数据。如果您的查询受I / O限制,则扫描磁盘上较少的数据会更快。但这是一个相当薄弱的解决方案。

您可以尝试使用InnoDB压缩来减少数据大小。这可能会让你更接近MyISAM大小,但你仍然受I / O限制,所以它会很糟糕。

最终,听起来您需要一个专为OLAP工作负载而设计的数据库,如数据仓库。 InnoDB和TokuDB都是为OLTP工作负载而设计的。

答案 1 :(得分:0)

它闻起来就像一个带有“报告”的数据仓库。通过明智地选择在什么时间段(典型的小时或天)聚合(选择您的Floats)的内容,您可以构建和维护可以更有效地为报告工作的摘要表。这具有仅扫描数据一次(以构建摘要)的效果,而不是重复扫描。摘要表格要小得多,因此报告速度要快得多 - 10倍也许是典型的。

当原始数据被插入时,也可以扩充Summary表。 (见INSERT .. ON DUPLICATE KEY UPDATE ..

并按日期使用分区以实现高效DROP PARTITION而不是DELETE。不要超过50个分区。

Summary Tables

Time series Partitioning

如果您想更详细地讨论,让我们从现在扫描的其中一个查询开始。

在我参与过的各种项目中,有2到7个汇总表。

使用600GB的数据,您可能会在“摄取”上限制。如果是这样,我们也可以讨论这个问题。