SELECT/UPDATE 和 SELECT/INSERT 杀死 MySQL 服务器

发布于 2024-09-10 20:34:32 字数 1959 浏览 0 评论 0原文

我运行的服务器因来自我们的一款 iPhone 游戏的存储分数的请求数量而被终止。我的意思是服务器变得无响应。

我只知道足够的 MySQL/PHP 来应付,所以我在尝试解决这个问题时陷入困境。我确信这是一个可以优化的问题,因为我们有专用服务器。我们每分钟仅处理 300 个请求。

基本上,我们检查某人从他们的 iPhone 游戏中发布的分数(使用 SELECT),看看他们是否有现有分数。如果他们这样做了,并且他们的新分数更好,我们会进行更新,否则我们会进行插入。这些语句看起来像这样:

$sql = "从 $table WHERE board='$board' AND name='$name' AND udid = '$udid' AND fbuid = '$fbuid' 中选择 id、score、level"

UPDATE 和 INSERT 语句如下所示:

$sql = "更新$table SET 分数='$score', level='$level',country='$country',date=CURRENT_TIMESTAMP WHERE board='$board' AND name='$name' AND udid = '$udid' AND fbuid = '$fbuid'"

$sql = "插入 $table(board, udid, fbuid, 姓名, 分数, 级别, 国家) VALUES ('$board', '$udid', '$fbuid', '$name', '$分数', '$level', $country')"

为了完整起见,以下是该表的定义:

创建表$table (
id int(11) NOT NULL auto_increment,
board tinyint(4) NOT NULL,
udid varchar(45) 默认 NULL,
fbuid bigint(20) 无符号默认 NULL,
name varchar(25) 默认 NULL,
国家 tinyint(4) 默认 NULL,
level tinyint(4) 默认 NULL,
分数 小数(10,0) 默认 NULL,
日期 时间戳 NOT NULL 默认 CURRENT_TIMESTAMP,
主键(id),
KEY scoreidx分数),
KEY udididx (udid),
KEY fbuididx (fbuid),
KEY boardidx (board),
KEY levelidx级别),
KEY countryidx国家/地区
) ENGINE=MyISAM 默认字符集=latin1

我当前使用以下方式从 PHP 连接到 MySQL 服务器:

$conn = mysql_pconnect(DB_HOST,DB_USER,DB_PASSWORD,MYSQL_CLIENT_INTERACTIVE);

但以前使用过 msql_connect ,但没有注意到它的改进。

任何有关如何优化此问题的指示,或任何描述我应该做什么的网页的链接将非常感激。

I run a server that is getting killed by the number of requests it is getting from one of our iPhone games for storing scores. By this I mean the server becomes unresponsive.

I only really know enough MySQL/PHP to get by, so I am floundering in my attempts to fix this. I am sure its a problem that can be optimised because we have a dedicated server. We handle only 300 requests a minute.

Basically we check the score someone is posting from their iPhone game (using a SELECT) to see if they have an existing score. If they do, and their new score is better, we do an UPDATE, otherwise we do an INSERT. The statements look like this:

$sql = "SELECT id,score,level FROM $table WHERE board='$board' AND name='$name' AND udid = '$udid' AND fbuid = '$fbuid'"

The UPDATE and INSERT statements look like this:

$sql = "UPDATE $table SET score='$score', level='$level', country='$country', date=CURRENT_TIMESTAMP WHERE board='$board' AND name='$name' AND udid = '$udid' AND fbuid = '$fbuid'"

$sql = "INSERT INTO $table(board, udid, fbuid, name, score, level, country) VALUES ('$board', '$udid', '$fbuid', '$name', '$score', '$level', $country')"

And for completeness, here is the definition for the table:

CREATE TABLE $table (
id int(11) NOT NULL auto_increment,
board tinyint(4) NOT NULL,
udid varchar(45) default NULL,
fbuid bigint(20) unsigned default NULL,
name varchar(25) default NULL,
country tinyint(4) default NULL,
level tinyint(4) default NULL,
score decimal(10,0) default NULL,
date timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY scoreidx (score),
KEY udididx (udid),
KEY fbuididx (fbuid),
KEY boardidx (board),
KEY levelidx (level),
KEY countryidx (country)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

I currently connect to the MySQL server from PHP using:

$conn = mysql_pconnect(DB_HOST,DB_USER,DB_PASSWORD,MYSQL_CLIENT_INTERACTIVE);

But used to use msql_connect previously, but did not notice an improvement with that.

Any pointers on how I can optimise this, or links to any web pages that describe what I should be doing would be HUGELY appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

朕就是辣么酷 2024-09-17 20:34:32

MyISAM 有表锁而不是 InnoDB 行锁。您可以创建表的副本,将引擎更改为 InnoDB,并(在测试服务器上)使用 mysqlslap 或类似的压力测试工具测试负载。

另外,非常重要的是:

ALTER TABLE tablename ADD INDEX(board,name,udid,fbuid)

MySQL 一次只能使用 1 个索引,因此当始终查询此特定组合时,几个“松散”的索引并没有多大用处。

MyISAM has table-locks instead of the InnoDB row-locks. You could create a copy of your table, alter the engine to InnoDB, and (on a testserver) test the load with mysqlslap or similar stress testing tools.

Also, very important:

ALTER TABLE tablename ADD INDEX(board,name,udid,fbuid)

MySQL can only use 1 index at a time, so your several 'loose' ones don't do that much good when always querying for this specific combination.

酒儿 2024-09-17 20:34:32

“MySQL 使用表级锁定
MyISAM、MEMORY 和 MERGE 表,
BDB 表的页级锁定,以及
InnoDB 表的行级锁定。”

http://dev.mysql.com/doc /refman/5.0/en/internal-locking.html

因此,每次更新时,整个表都会获得一个锁,您可能需要切换到 InnoDB。

"MySQL uses table-level locking for
MyISAM, MEMORY and MERGE tables,
page-level locking for BDB tables, and
row-level locking for InnoDB tables."

http://dev.mysql.com/doc/refman/5.0/en/internal-locking.html

So, each time you update, the full table gets a lock. You might want to switch to InnoDB.

装纯掩盖桑 2024-09-17 20:34:32

您可以尝试通过不对重复的主键进行选择和更新来进行优化。您将需要一个主键,例如电子邮件地址或其他内容。

$sql = "INSERT INTO $table(board, udid, fbuid, name, score, level, country) VALUES
('$board', '$udid', '$fbuid', '$name', '$score', '$level', $country') ON DUPLICATE KEY
UPDATE score = '$score'";

you could try optimizing by not doing the select and updating on duplicate primary key.. You would need a primary key like email address or something though.

$sql = "INSERT INTO $table(board, udid, fbuid, name, score, level, country) VALUES
('$board', '$udid', '$fbuid', '$name', '$score', '$level', $country') ON DUPLICATE KEY
UPDATE score = '$score'";
月竹挽风 2024-09-17 20:34:32

==抱歉,语言错误,但可以使用行文本文件来完成。
如果是传入连接的数量,您可能需要在游戏二进制文件中创建一个计时器单元来调用和接收以查找是否必须重试,同时保存从网络服务器交换回游戏的带有令牌编号的数据(队列上的数据作业(例如 EJB)。
当每个步骤被​​验证发生时,游戏中的计时器和等待过程可以停止。
在 Web 服务器 ServletContext 中,持久对象用于存储带有 Id 令牌的作业,以及保存令牌和作业完成状态的镜像列表。
这样,MySQL 的网络服务器可以简单地逐一处理该列表,直到它被游戏请求和输入到例如 hashmao 列表中的数据重新触发。

==sorry wrong language but could be done with a text file of lines.
If it is the number of incoming connections, you may need to make a timer unit In the game binaries to call and receive to find if it must retry, while holding the data with a token number exchanged back to the game from the web server (data jobs on a queue e.g. EJB).
When each step is verified occured the timer and waiting process in the game can be stopped.
In the web server ServletContext persistent object to store jobs with an I'd token, and a mirror List holding token and job completed status.
That way, the webserver to MySQL can simply work through the list one by one until it is retriggered by a game request and data entered in e.g. the hashmao List.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文