Mysql 根据用户拆分数据库';身份证
我有一个500万行的数据库,它不断增长,使用它进行操作变得越来越困难 将表拆分为10个表(v0\u表、v1\u表……v9\u表)是一个好主意,其中数字(v*)是用户id的第一个数字 在我的例子中,用户id不是自动递增的,因此它将在这10个表中对数据进行均匀排序 问题是我从来没有做过类似的事情 有人能看出缺点吗 编辑: 如果您能帮助我调整结构或查询,我将不胜感激。 因此,最慢的查询是以下查询:Mysql 根据用户拆分数据库';身份证,mysql,query-optimization,Mysql,Query Optimization,我有一个500万行的数据库,它不断增长,使用它进行操作变得越来越困难 将表拆分为10个表(v0\u表、v1\u表……v9\u表)是一个好主意,其中数字(v*)是用户id的第一个数字 在我的例子中,用户id不是自动递增的,因此它将在这10个表中对数据进行均匀排序 问题是我从来没有做过类似的事情 有人能看出缺点吗 编辑: 如果您能帮助我调整结构或查询,我将不胜感激。 因此,最慢的查询是以下查询: SELECT logos.user, logos.date, logos
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 | |
+--------+------------+------+-----+-------------------+----------------+
标识表:
+-------+--------------+------+-----+-------------------+----------------+
| 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 | |
+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+
简短而甜蜜:不,这从来不是个好主意。您的表是否正确索引?MySQL是否正确调整?您的查询是否高效?您正在使用缓存吗?您可能希望检查数据库中的其他表,看看它们是否可以拆分为其他数据库,而不是对表进行切分。例如,从未连接到的表就是这种垂直分区的最佳候选表
这允许您为较小的数据集优化硬件。您的问题不是数据太多,而是这些数据没有正确索引。尝试添加索引:
CREATE INDEX open_level ON logos(open, level)
这应该避免使用临时的;在徽标上使用文件排序
基本上,这个查询需要在这个表上建立一个索引来覆盖两件事:open-for
其中open='1'
和level-for按级别分组,因为MySQL将首先按open进行筛选,然后按级别对结果进行分组(在处理过程中隐式地按其排序).这似乎会让查询变得非常混乱。在我可以使用的地方使用memcache,也增加了mysql缓存,索引了表(如果正确的话不知道)。问题是有500个用户在线,而且该表经常更新。。。为什么这不是一个好主意?以不同的方式拆分表可能有意义,但不是您在OP中建议的方式。许多数据库将“频繁更新”字段与已完成的“几乎从未更新”字段分开放在一个表中。我只是在寻求额外的改进。即使现在只有我在线时,也需要0.3秒才能获得30个条目(从5.2百万开始)。但是当500个用户在线时,它会变得疯狂。在我看来,这些表的索引不正确。您是否设置并检查了mysql慢速查询日志?设置好,然后对这些语句进行“解释”,看看它们是否使用索引,然后进行相应的调整。除此之外,如果看不到具体的表结构,将很难提供帮助。在我看来,不这样做的原因列表相当长,但基本上可以归结为维护和数据完整性。我在表的结构上添加了更多细节。我将非常感谢您的帮助。这里的问题是我有3个表,其中2个经常使用。所以第三个是独立的,通常是memcached。你能告诉我为什么分裂是个坏主意吗?理论上,分裂不是个坏主意。您可以并行化查询,使用更小的索引,等等。实际上,MySQL并不是很适合这样做。根据我的经验,拆分表并独立地调优每一组表更容易。MySQL确实支持分区功能,但我不确定它在实践中的效果如何。你能解释一下它是做什么的,为什么它只包含“开放”和“级别”吗?老实说,这个索引很有用。将CPU负载降低20%。谢谢:)虽然OP有所不同,但您帮助了优化的最终请求。