我运行的服务器因为从我们的iPhone游戏中获取的用于存储分数的请求数量而被杀死。我的意思是服务器没有响应。
我真的只知道足够的MySQL / PHP,所以我在尝试解决这个问题时陷入困境。我确信这是一个可以优化的问题,因为我们有一个专用的服务器。我们每分钟只处理300个请求。
基本上我们检查某人从他们的iPhone游戏中发布的分数(使用SELECT)来查看他们是否有现有分数。如果他们这样做,并且他们的新分数更好,我们会进行更新,否则我们会进行INSERT。这些陈述如下:
$ sql =“SELECT id,score,level FROM $ table WHERE board ='$ board'AND name ='$ name'AND udid ='$ udid'AND fbuid ='$ fbuid'”
UPDATE和INSERT语句如下所示:
$ sql =“UPDATE $ table SET score ='$ score',level ='$ level',country ='$ country',date = CURRENT_TIMESTAMP WHERE board ='$ board'AND name ='$ name'AND udid ='$ udid'和fbuid ='$ fbuid'“
$ sql =“INSERT INTO $ table(board,udid,fbuid,name,score,level,country)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,
country
tinyint(4)默认为NULL,
level
tinyint(4)默认为NULL,
score
十进制(10,0)默认为NULL,
date
时间戳NOT NULL默认CURRENT_TIMESTAMP,
PRIMARY KEY(id
),
KEYscoreidx
(score
),
KEYudididx
(udid
),
KEYfbuididx
(fbuid
),
KEYboardidx
(board
),
KEYlevelidx
(level
),
KEYcountryidx
(country
)
)ENGINE = MyISAM DEFAULT CHARSET = latin1
我目前使用以下方法从PHP连接到MySQL服务器:
$ conn = mysql_pconnect(DB_HOST,DB_USER,DB_PASSWORD,MYSQL_CLIENT_INTERACTIVE);
但之前曾经使用msql_connect,但没有注意到它的改进。
关于我如何优化这一点的任何指示,或链接到描述我应该做什么的任何网页都将非常感激。
答案 0 :(得分:4)
MyISAM具有表锁而不是InnoDB行锁。您可以创建表的副本,将引擎更改为InnoDB,并(在测试服务器上)使用mysqlslap
或类似的压力测试工具测试负载。
另外,非常重要:
ALTER TABLE tablename ADD INDEX(board,name,udid,fbuid)
MySQL一次只能使用1个索引,所以当你总是查询这个特定组合时,你的几个“松散”索引并没有那么好。
答案 1 :(得分:1)
“MySQL使用表级锁定 MyISAM,MEMORY和MERGE表, BDB表的页级锁定,以及 InnoDB表的行级锁定。“
http://dev.mysql.com/doc/refman/5.0/en/internal-locking.html
因此,每次更新时,完整表都会获得锁定。您可能想切换到InnoDB。
答案 2 :(得分:0)
您可以尝试通过不对重复的主键进行选择和更新来优化..您需要一个主键,如电子邮件地址或其他东西。
$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'";