【求助】MySQL 大数据分表思路 千万级数据

用户昵称不能为空 2013-08-16 03:04:44
现有:用户账号表nick,购买记录表log;
需求:实时查询功能, 通过表log.title 的模糊查询,得到表 nick的记录。表nick.uid=log.uid 对应关系。
分表:因为数据比较多 nick已经有9千万,log已经有300万数据;现在nick表查询起来就非常慢,log肯定会比nick更大,因为一个用户平均至少几个购买记录。


如果nick要分表如何分?
1)想到的是uid段来分,但是表nick中的uid不是连续的,中间有断的。而且uid跨越非常大,1到10亿,且不是连续。
2)如果nick分表,log估计也得分表。logo与nick都是多表,那么如何查询?(程序得改很多...)
如果这样分表,关键问题是nick 的uid值不是连续的,最小是有10以下,最大上亿。分得100万一个区间得无数个表,分得1亿一个区间表,跟不分表的效果没多大区别(发现MySQL一旦超过100万就开始慢了)。


表nick1、nick2、nick3、nick4是提供的数据

mysql> SELECT COUNT(uid),MIN(uid),MAX(uid) FROM nick1
-> UNION SELECT COUNT(uid),MIN(uid),MAX(uid) FROM nick2
-> UNION SELECT COUNT(uid),MIN(uid),MAX(uid) FROM nick3
-> UNION SELECT COUNT(uid),MIN(uid),MAX(uid) FROM nick4;
+------------+----------+--------------+
| COUNT(uid) | MIN(uid) | MAX(uid) |
+------------+----------+--------------+
| 38558758 | 31 | 133152982928 |
| 36101731 | 2 | 133153067302 |
| 12610937 | 87 | 133151412359 |
| 886706 | 533 | 1729210852 |
+------------+----------+--------------+
4 rows in set (1 min 14.58 sec)





这几个表都是nick这样的结构:

mysql> DESC nick;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| uid | bigint(20) | NO | PRI | NULL | |
| nick | varchar(30) | NO | | NULL | |
+-----------+-------------+------+-----+---------+-------+
2 rows in set (0.02 sec)




有没有其他的方法或者更好的方法,求
...全文
374 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 1 楼 rucypli 的回复:
模糊搜索肯定是不行的 首要任务是做title的全文索引
我现在只需求简单查询分页列出,不需要模糊查询,但是需要分页。

mysql> SELECT MIN(uid),MAX(uid),COUNT(uid) FROM nick;
+----------+--------------+------------+
| MIN(uid) | MAX(uid)     | COUNT(uid) |
+----------+--------------+------------+
|        2 | 133153067302 |   88090625 |
+----------+--------------+------------+
1 row in set (0.00 sec)
分页用LIMIT,每页1000条,当达页数达到很大的时候,查询基本上死机,必须重启MYSQL :

mysql> EXPLAIN
    -> SELECT * FROM nick ORDER BY uid ASC LIMIT 90000000,100;
+----+-------------+---------+------+---------------+------+---------+------+----------+----------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows     | Extra          |
+----+-------------+---------+------+---------------+------+---------+------+----------+----------------+
|  1 | SIMPLE      | nick    | ALL  | NULL          | NULL | NULL    | NULL | 88090625 | Using filesort |
+----+-------------+---------+------+---------------+------+---------+------+----------+----------------+
1 row in set (0.00 sec)
我现在用的方法是指定ID范围扫描,但是uid不是连续的,且nick表也在不停的增删纪录。

mysql> EXPLAIN
    -> SELECT * FROM nick WHERE uid>2010000 AND uid<2020000 ORDER BY uid ASC;

+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table   | type  | possible_keys | key     | key_len | ref| rows | Extra       |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | nick    | range | PRIMARY       | PRIMARY | 8       | NULL|    1 | Using where |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
  • 打赏
  • 举报
回复
引用 1 楼 rucypli 的回复:
模糊搜索肯定是不行的 首要任务是做title的全文索引
给表log.title (text类型)加全文索引,然后使用LIKE 查询 log.title字段对吗? 表nick如何分有没有建议,求
rucypli 2013-08-16
  • 打赏
  • 举报
回复
模糊搜索肯定是不行的 首要任务是做title的全文索引

56,679

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧