如何解决Mysql 计算两个日期条件之间非常大的行的性能
我在 Innodb 中有一个超过 2000 万行的表。
列是
id,viewable_id,visitor,viewed_at
其中 viewable_id
和 viewed_at
是索引。
当我执行以下查询时
SELECT COUNT(*)
FROM views_users
WHERE (viewable_id = 2)
and (viewed_at between '2021-04-19 01:38:37'
and '2021-06-30 01:38:37');
=> 拍摄(3 分 6.72 秒)
解释是
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+-----------------------------------------------------------+-------------------------------+---------+-------+---------+----------+-------------+
| 1 | SIMPLE | views_users | NULL | ref | views_users_viewable_id_index,views_users_viewed_at_index | views_users_viewable_id_index | 8 | const | 9554594 | 50.00 | Using where
如何将性能提高到不到 4 秒?
CREATE TABLE views_users (
id int unsigned NOT NULL AUTO_INCREMENT,viewable_type varchar(255) NOT NULL,viewable_id bigint unsigned NOT NULL,visitor text,collection varchar(255) DEFAULT NULL,viewed_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id),KEY user_id (viewable_id)
) ENGINE=InnoDB AUTO_INCREMENT=20995848
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
解决方法
我通过应用 MySQL partiotons 将性能提高到不到 2 秒。
我使用 viewed_at
列按范围分区。将 viewed_at
类型从 timestamp
更改为 datatime
,并使用 id
将其设为主键。
在每个月的第一天运行 cronjob,将最后一个分区重组为另一个分区,依此类推。
对于这个查询:
from .module_B import function_b
您可以创建索引:
SELECT COUNT(*)
FROM views_users
WHERE viewable_id = 2 and
viewed_at between '2021-04-19 01:38:37' and '2021-06-30 01:38:37';
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。