0

简介:有什么方法可以提高对 InnoDB 表的表扫描性能?

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

innodb_buffer_pool_size 占服务器内存的 75% (48 GB/64GB) 如果有任何改变,我正在使用最新版本的 Percona (5.7.19)

更长:我们有 600Gb 的最近时间序列数据(我们汇总和删除旧数据)分布在 50-60 个表中。因此,其中大部分是定期查询的“活动”数据。这些表有点大(400 多个数字列),许多查询针对其中的一些列(令人担忧)运行,这就是为什么添加索引是不切实际的(因为我们必须添加几十个)。每天对最大的表进行分区。

我完全意识到这是一个应用程序/表设计问题,而不是“服务器调优”问题。我们目前正在努力显着改变这些表的设计和查询方式,但必须维护现有系统直到发生这种情况,所以我正在寻找一种方法来稍微改进一下,为我们争取一点时间。

我们最近拆分了这个系统,并将其中的一部分移到了新服务器上。它以前使用 MyISAM,我们尝试迁移到 TokuDB,这似乎很合适,但遇到了一些奇怪的问题。我们切换到 InnoDB,但性能真的很差。我的印象是 MyISAM 在表扫描方面更好,这就是为什么,除非有更好的选择,否则我们会回到它,直到新系统到位。

更新

所有表都具有几乎相同的结构:-timestamp -主键(varchar(20) 字段)-大约 15 个不同类型的字段,表示可以过滤的其他辅助属性(首先带有适当的索引标准)-然后大约几百个措施(浮动),在 200-400 之间。

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

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

仅使用我需要的一组列创建小表将有助于一些流程执行得更快。但代价是首先使用表扫描创建该表并复制数据。也许如果我将它创建为内存表。据我估计,缓冲池需要几 GB 的空间。还有一些聚合过程会定期从主表中读取尽可能多的数据,并且它们需要所有列。

不幸的是,在我计划在下一个版本中解决的那些查询中有很多重复的工作。每次插入一些行(每半小时)时,警报和聚合过程基本上都会重新处理一整天的数据,而不仅仅是处理新的/更改的数据。

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

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

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

4

2 回答 2

1

MyISAM 在表扫描方面要好一些,因为它比 InnoDB 更紧凑地存储数据。如果您的查询是 I/O 密集型的,那么扫描磁盘上较少的数据会更快。但这是一个非常薄弱的​​解决方案。

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

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

于 2018-05-16T17:45:18.053 回答
0

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

也可以在插入原始数据时扩充汇总表。(见INSERT .. ON DUPLICATE KEY UPDATE ..

并使用按日期分区以允许高效DROP PARTITION而不是DELETE. 不要有超过 50 个分区。

汇总表

时间序列分区

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

在我从事的各种项目中,有 2 到 7 个汇总表。

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

于 2018-05-23T03:14:26.330 回答