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

时间:2010-07-20 21:43:18

标签: php mysql query-optimization

我运行的服务器因为从我们的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),
    KEY scoreidxscore),
    KEY udididxudid),
    KEY fbuididxfbuid),
    KEY boardidxboard),
    KEY levelidxlevel),
    KEY countryidxcountry
    )ENGINE = MyISAM DEFAULT CHARSET = latin1

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

  

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

但之前曾经使用msql_connect,但没有注意到它的改进。

关于我如何优化这一点的任何指示,或链接到描述我应该做什么的任何网页都将非常感激。

3 个答案:

答案 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'";