【发布时间】:2020-09-06 17:09:00
【问题描述】:
我在 mysql 中有一个表,其中大约 7000 亿行用于表示聊天消息。文本存储在单独的表格中。
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
| Type | tinyint(4) | NO | | 0 | |
| FromUserID | int(10) unsigned | NO | PRI | 0 | |
| ToUserID | int(10) unsigned | YES | MUL | NULL | |
| TextID | int(10) unsigned | YES | MUL | NULL | |
| Ts | datetime | YES | | NULL | |
| IsNew | tinyint(4) | NO | | 0 | |
| Direction | tinyint(4) | NO | | 0 | |
| NeedStar | tinyint(4) | NO | | 0 | |
| NeedSend | tinyint(4) | NO | | 0 | |
| DirectID | int(10) unsigned | YES | MUL | NULL | |
| IdeaID | int(11) | YES | | NULL | |
| FilePos | int(11) | NO | | 0 | |
+------------+------------------+------+-----+---------+----------------+
到目前为止,它已被分区BY HASH(FromUserID) PARTITIONS 16; 并索引如下:
--------------------+--------------+-------------+-----------+-------------+
Key_name | Seq_in_index | Column_name | Collation | Cardinality |
--------------------+--------------+-------------+-----------+-------------+
PRIMARY | 1 | ID | A | 644937873 |
PRIMARY | 2 | FromUserID | A | 644937873 |
DoulikeMessage_k_2 | 1 | FromUserID | A | 5971646 |
DoulikeMessage_k_2 | 2 | ToUserID | A | 644937873 |
DoulikeMessage_k_3 | 1 | DirectID | A | 28 |
ToUserID | 1 | ToUserID | A | 37937521 |
TextID | 1 | TextID | A | 644937873 |
--------------------+--------------+-------------+-----------+-------------+
我正在考虑创建一个具有不同分区和索引的类似表,然后在那里传输记录。对表最频繁的查询是
SELECT DoulikeMessages.* FROM DoulikeMessages WHERE 1 AND (DoulikeMessages.FROMUSERID = '2048254') AND DoulikeMessages.TOUSERID >= '1' AND DoulikeMessages.TYPE <= '1' ORDER BY Ts DESC;
有时需要长达 20 秒的时间来处理。那是因为 Ts (datetime) 上没有索引。我考虑做类似PARTITION BY RANGE( FromUserID ) PARTITIONS 50 的事情。并按 Ts 索引。或者也许我应该按日期制作子分区?我可以在查询中添加诸如“Where TS > now()- 1 Month”之类的内容,因为大多数时候只需要最近的消息。而旧的只是稍后在代码中被丢弃。
另外我应该提到有人尝试手动分区表(基于 fromuserid 创建 50 个新表并更改 api 以使用它们),但这对我来说似乎是个坏主意。我不明白如何从这种方法中受益。
【问题讨论】:
标签: mysql database-partitioning