Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL复制和表锁_Mysql_Replication - Fatal编程技术网

MySQL复制和表锁

MySQL复制和表锁,mysql,replication,Mysql,Replication,我有以下问题 我有一个基于PHP和MySQL的MMORPG游戏,现在平均每秒大约有600个查询。 我碰巧遇到了表锁定时间太长,导致其他查询受阻的问题。(例如,更新查询需要等待Select查询),而这些查询必须等待很长时间,以致内存已满 这些查询是需要的,我认为我不能再优化它们了 将复制用于主从机是否明智?写入的主设备和选择的从设备? 从机的写语句(从日志箱)性能问题是否比主机少?它真的能帮助减少表锁问题吗 提前谢谢你,马丁 啊,好的,谢谢你的回答。 因此,如果我使用InnoDB处理这些表。把它

我有以下问题

我有一个基于PHP和MySQL的MMORPG游戏,现在平均每秒大约有600个查询。 我碰巧遇到了表锁定时间太长,导致其他查询受阻的问题。(例如,更新查询需要等待Select查询),而这些查询必须等待很长时间,以致内存已满

这些查询是需要的,我认为我不能再优化它们了

将复制用于主从机是否明智?写入的主设备和选择的从设备? 从机的写语句(从日志箱)性能问题是否比主机少?它真的能帮助减少表锁问题吗

提前谢谢你,马丁


啊,好的,谢谢你的回答。 因此,如果我使用InnoDB处理这些表。把它们和MyISAM混在一起聪明吗

因为使用MyISAM的测试表是70MB,而使用InnoDB的测试表是200MB。我希望有一些表与InnoDB的tablelocks有问题,而其他的只是MyISAM


提前感谢您,Martin。

在您考虑复制和其他问题之前,请尝试以下方法:

我假设您的表正在使用MyISAM。
MyISAM在select上锁定整个表,并使更新等待,直到select完成

<强>在考虑复制

之前要考虑的几个想法 使用InnoDB
将您的表切换到InnoDB。
InnoDB执行行锁定而不是表锁定。只有更新并选中的行才会被锁定

考虑使用聚合表
如果执行大量聚合查询,如:

select sum(score) from score where player_id = 1
考虑如下制作
内存
表:

CREATE TABLE `test`.`totals` (
  `user_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `score` INTEGER UNSIGNED NOT NULL,
  other_fields .....
  PRIMARY KEY  USING HASH(`user_id`)
)
ENGINE = MEMORY;
在更新之后放置触发器
,在插入之后放置触发器
,如下所示:

DELIMITER $$

CREATE TRIGGER au_score_each AFTER UPDATE ON score FRO EACH ROW
BEGIN
  UPDATE totals SET score = score + (new.score - old.score) 
  WHERE totals.user_id = new.user_id;
END $$

DELIMITER ;
现在,您可以从
totals
表中获取聚合
select
查询,并且不再需要在完整的表中插入数据库

关于主从的几点评论
请注意,MySQL中的主从是异步的。这意味着,如果从从属设备中选择并在主设备上更新,则从属设备数据将落后。
这意味着您正在用锁定问题换取时滞问题。
在有分数的游戏中,这可能是个问题。
此外,您正在使设置复杂化


我不是复制方面的专家,所以我就到此为止,但我认为在探索替代方案之前,您正在跳入主从模式

从机更新是单线程的,只需重复在主机上执行的更新即可。因此,尽管您可能会从单个从机获得一个小的速度提升,但您确实需要有多个从机才能显著提高选择速度。这将显著增加游戏的复杂性


如果您可以升级您的服务器,那么我建议您首先还要查看MySQL的可调参数,确保充分利用可用内存等。

Martin,欢迎使用stackoverflow。我已经合并了您的两个未注册帐户。您现在可以编辑您的问题,并在个人答案下留下评论。啊,好吧,我怀疑我的系统能否处理几个从属项S我现在将介绍如何使用InnoDB,如下所示。(谢谢约翰!)谢谢你们两位的回答!