简介:有什么方法可以提高对 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 倍),这确实阻碍了性能。