【发布时间】:2020-07-25 04:01:52
【问题描述】:
我在 mySQL 上有一个最近的活动表,它的 MyISAM 包含大约 4600 万条记录。它已正确编入索引,并且所有这些都已完成。但有些查询仍然需要几秒钟的时间来执行。
所以我想知道,在这个数据库上提高查询性能的最佳方法是什么。我应该对表进行分区还是删除旧数据?我主要对这个月的数据进行一些计算来查询,另一个用途是向用户展示他们最近的活动,以及我们不得不不时手动监控他们的活动。
我一直在考虑删除所有早于今年的数据,这应该会删除大约 2400 万行。 (因为从本月初开始已经 4 个月了,所以旧的数据应该不那么重要了)。
或者我可以按月份进行分区,但我不知道在 laravel 中如何实现,我是否每次都必须更改分区才能获取比当前月份更早的数据?
编辑: 这 1 个查询是一个重要的查询,它是在用户的特定活动之后执行的,此特定查询需要 8 秒才能执行,并且使用 user_id 索引经过了 40,000 行。 如果它使用多个索引,将有助于我改进此查询,因为这样查询将被缩小到非常少的行。或者,如果我删除旧数据,那么完成计算所需的行数就会减少。
select *
from `recent_activites`
where `id` > 20443580
and `user_id` = 20580
and `updated_at` > '2020-04-01 00:00:00'
and `type` in (?, ?, ?, ?, ?, ?, ?, ?, ?) ```
编辑: 询问 : 此查询在 1 次执行时花费了 8.72 毫秒,但似乎总是花费超过 1 毫秒 时间存在是因为它减少了行数
【问题讨论】:
-
你也可以考虑在 laravel 中使用缓存想想 redis。
-
是的,我也有很多缓存要做,但是这些数据必须经常更新。缓存运行得非常好,它使我们的 cpu 使用率从 50% 降低到 20%,但我仍然每 3 小时为用户更新一次。但是对于第一次数据刷新它仍然很慢
-
您在此处公开的两种方法都可以使用,您也可以进行复制,但您应该考虑如果不是,则删除数据是否是个好主意,您有答案。你也可以重新考虑你的数据库设计,避免像连接这样的事情。这取决于您在此处尝试实现的目标,但您甚至可以使用多个数据库。也许你应该更具体
-
我对分区没有直接经验,但我的一位 MySQL 专家同事说分区是邪恶的。我会改为使用复制或缓存解决方案。
-
在您进行一般设置更改(除了从 MyISAM 移走)或删除您可能仍需要的数据之前,我会质疑您的前提 “它已被正确索引并且所有这些都已完成。”。例如。从您的描述和查询性能来看,听起来您只有单列索引,而您的给定查询需要复合索引,
(user_id, updated_at)可能就足够了。如果您需要这方面的帮助,您应该始终提供查询、表结构 (show create table ...) 和执行计划(在查询前写上explain)和时间。