MySQL 分区或删除旧数据?
MySQL partitioning or deleting older data?
我最近在 mySQL 上进行了一项活动 table,它的 MyISAM 包含大约 4600 万条记录。它已正确编入索引,所有这些都已完成。但是一些查询仍然需要几秒钟才能对其执行。
所以我想知道,提高该数据库查询性能的最佳方法是什么。我应该分区 table 还是删除旧数据?我主要是对这个月的数据进行一些计算来查询,另一个用途是向用户展示他们最近的活动,以及我们不得不时不时地手动监控他们的活动。
我一直想删除所有比今年早的数据,应该删除大约2400万行。 (因为从本月初到现在已经有 4 个月了,所以那么旧的数据应该没有那么重要)。
或者我可以按月分区,但我不知道在 laravel 中如何实现,我是否必须每次更改分区才能获取比当前月份更早的数据?
编辑:
这个 1 查询是一个重要的查询,它是在用户的特定 activity 之后执行的,这个特定查询执行了 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 毫秒
时间在那里,因为它减少了行
这些是索引
- 删除那么多 table 时,复制要保留的行会更快。
- 你应该从 MyISAM 转移到 InnoDB。
PARTITIONing
将有助于将来清除旧数据。
- 添加
PARTITIONing
会花费时间。删除旧数据的任何技术也是如此。哪个更重要?减少堵塞?或者完成任务的速度。
PARTITIONing
本身不会加快查询速度。但是,您似乎需要一个“二维”索引。
- 您在进行分区时必须重新考虑索引。
- 摘要 table 可能会显着提高性能。
以上几个步骤可以同时完成——切换到InnoDB,添加分区,删除旧数据,更改索引。 (摘要 tables 是一个单独的任务。)我建议在处理您的实时系统之前进行试验。
参考文献:
- 切换到 InnoDB:http://mysql.rjweb.org/doc.php/myisam2innodb
- 分区——优点、缺点、指南、时间序列代码:http://mysql.rjweb.org/doc.php/partitionmaint
- 大
DELETEs
-- 多种技术,它们的优缺点:http://mysql.rjweb.org/doc.php/deletebig
- 摘要table秒:http://mysql.rjweb.org/doc.php/summarytables
您可以将一些数据移动到存档数据库,我的意思是将旧数据存储在单独的数据库(存档)中,将实际数据存储在当前数据库中。在这种情况下,您仍然可以对实际(新)数据有良好的性能,并且可以同时访问旧数据。
要处理此问题,您需要在 Laravel 系统中设置 2 个连接 - 在 config/database.php
中创建新连接。
现在您应该可以像这样访问您的存档数据了:
$archive_data = DB::connection('name_of_archive_connection')->table('table_name')->select('*')...
$actual_data = DB::connection('name_of_main_connection')->table('table_name')->select('*')...
您还可以通过 insert/delete mysql 功能轻松地在数据库之间移动数据,如上例所示。
我最近在 mySQL 上进行了一项活动 table,它的 MyISAM 包含大约 4600 万条记录。它已正确编入索引,所有这些都已完成。但是一些查询仍然需要几秒钟才能对其执行。
所以我想知道,提高该数据库查询性能的最佳方法是什么。我应该分区 table 还是删除旧数据?我主要是对这个月的数据进行一些计算来查询,另一个用途是向用户展示他们最近的活动,以及我们不得不时不时地手动监控他们的活动。
我一直想删除所有比今年早的数据,应该删除大约2400万行。 (因为从本月初到现在已经有 4 个月了,所以那么旧的数据应该没有那么重要)。
或者我可以按月分区,但我不知道在 laravel 中如何实现,我是否必须每次更改分区才能获取比当前月份更早的数据?
编辑: 这个 1 查询是一个重要的查询,它是在用户的特定 activity 之后执行的,这个特定查询执行了 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 毫秒 时间在那里,因为它减少了行
这些是索引
- 删除那么多 table 时,复制要保留的行会更快。
- 你应该从 MyISAM 转移到 InnoDB。
PARTITIONing
将有助于将来清除旧数据。- 添加
PARTITIONing
会花费时间。删除旧数据的任何技术也是如此。哪个更重要?减少堵塞?或者完成任务的速度。 PARTITIONing
本身不会加快查询速度。但是,您似乎需要一个“二维”索引。- 您在进行分区时必须重新考虑索引。
- 摘要 table 可能会显着提高性能。
以上几个步骤可以同时完成——切换到InnoDB,添加分区,删除旧数据,更改索引。 (摘要 tables 是一个单独的任务。)我建议在处理您的实时系统之前进行试验。
参考文献:
- 切换到 InnoDB:http://mysql.rjweb.org/doc.php/myisam2innodb
- 分区——优点、缺点、指南、时间序列代码:http://mysql.rjweb.org/doc.php/partitionmaint
- 大
DELETEs
-- 多种技术,它们的优缺点:http://mysql.rjweb.org/doc.php/deletebig - 摘要table秒:http://mysql.rjweb.org/doc.php/summarytables
您可以将一些数据移动到存档数据库,我的意思是将旧数据存储在单独的数据库(存档)中,将实际数据存储在当前数据库中。在这种情况下,您仍然可以对实际(新)数据有良好的性能,并且可以同时访问旧数据。
要处理此问题,您需要在 Laravel 系统中设置 2 个连接 - 在 config/database.php
中创建新连接。
现在您应该可以像这样访问您的存档数据了:
$archive_data = DB::connection('name_of_archive_connection')->table('table_name')->select('*')...
$actual_data = DB::connection('name_of_main_connection')->table('table_name')->select('*')...
您还可以通过 insert/delete mysql 功能轻松地在数据库之间移动数据,如上例所示。