根据用户ID拆分数据库

时间:2012-06-19 00:52:31

标签: mysql query-optimization

我有一个5米行的数据库,它会增长,并且越来越难以进行操作。

将表拆分为10个表(v0_table,v1_table ... v9_table)是不是一个好主意,其中数字(v *)是用户id的第一个数字?

在我的情况下,用户的id不会自动递增,因此它会在这10个表中均匀地对数据进行排序。

问题是我从未做过类似的事情......

有人能发现任何缺点吗?

编辑:

我将非常感谢您在调整结构或查询时提供帮助。 所以最慢的查询是以下一个:

SELECT logos.user, 
       logos.date, 
       logos.level, 
       logos.title, 
       Count(guesses.id), 
       Sum(guesses.points) 
FROM   logos 
       LEFT JOIN guesses 
              ON guesses.user = '".$user['uid']."' 
                 AND guesses.done = '1' 
                 AND guesses.logo = logos.id 
WHERE  open = '1' 
GROUP  BY level 

猜猜表:

+--------+------------+------+-----+-------------------+----------------+
| Field  | Type       | Null | Key | Default           | Extra          |
+--------+------------+------+-----+-------------------+----------------+
| id     | int(11)    | NO   | PRI | NULL              | auto_increment |
| logo   | int(11)    | NO   | MUL | NULL              |                |
| user   | int(11)    | NO   | MUL | NULL              |                |
| date   | timestamp  | NO   |     | CURRENT_TIMESTAMP |                |
| points | int(4)     | YES  | MUL | 100               |                |
| done   | tinyint(1) | NO   | MUL | 0                 |                |
+--------+------------+------+-----+-------------------+----------------+

LOGOS表:

+-------+--------------+------+-----+-------------------+----------------+
| Field | Type         | Null | Key | Default           | Extra          |
+-------+--------------+------+-----+-------------------+----------------+
| id    | int(11)      | NO   | PRI | NULL              | auto_increment |
| name  | varchar(100) | NO   |     | NULL              |                |
| img   | varchar(222) | NO   | MUL | NULL              |                |
| level | int(3)       | NO   | MUL | NULL              |                |
| date  | timestamp    | NO   | MUL | CURRENT_TIMESTAMP |                |
| user  | int(11)      | NO   | MUL | NULL              |                |
| open  | tinyint(1)   | NO   | MUL | 0                 |                |
+-------+--------------+------+-----+-------------------+----------------+

说明:

+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+
| id | select_type | table   | type | possible_keys  | key  | key_len | ref   | rows | Extra                                        |
+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+
|  1 | SIMPLE      | logos   | ref  | open           | open | 1       | const |  521 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | guesses | ref  | done,user,logo | user | 4       | const |   87 |                                              |
+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+

3 个答案:

答案 0 :(得分:0)

简短而甜蜜:不。这绝不是个好主意。您的表格是否正确编入索引? MySQL是否经过适当调整?您的查询有效吗?你在使用任何缓存吗?

答案 1 :(得分:0)

您可能希望检查数据库中的其他表,以查看它们是否可以拆分为其他dbs,而不是对表进行分片。例如,从未加入的表格是这种垂直分区的理想选择。

这使您可以针对较小的数据集优化硬件。

答案 2 :(得分:0)

您的问题不在于您有太多数据,而是这些数据没有正确编入索引。尝试添加索引:

CREATE INDEX open_level ON logos(open, level)

这应该消除使用临时;在徽标上使用filesort

基本上,您需要此表的索引才能涵盖以下两项内容: open - WHERE open = '1' level - {{1}按此顺序,因为MySQL将首先按打开进行过滤,然后按级别对结果进行分组(在进程中隐式排序)。