1

我有一个 500 万行的数据库,并且它不断增长,并且越来越难以使用它进行操作。

将表拆分为 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                 |                |
+--------+------------+------+-----+-------------------+----------------+

LOGO表:

+-------+--------------+------+-----+-------------------+----------------+
| 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 |                                              |
+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+
4

3 回答 3

0

简短而甜蜜:不。这绝不是一个好主意。您的表是否正确索引?MySQL是否正确调整?您的查询效率高吗?您是否使用任何缓存?

于 2012-06-19T01:01:06.837 回答
0

Instead of sharding your table, you may want to examine other tables in your database to see if they can be split off into other dbs. For example tables, that are never joined to are great candidates for this type of vertical partitioning.

This allows you to optimize hardware for smaller sets of data.

于 2012-06-19T01:05:00.643 回答
0

Your problem isn't that you have too much data, it's that this data is not properly indexed. Try adding an index:

CREATE INDEX open_level ON logos(open, level)

This should eliminate Using temporary; Using filesort on logos.

Basically, you need an index on this table for this query to cover two things: open - for WHERE open = '1' and level - for GROUP BY level in this order, as MySQL will first filter by open, then will group the results by level (implicitly sorting by it in process).

于 2012-06-19T11:19:10.847 回答