[英]SELECT/UPDATE and SELECT/INSERT kills MySQL server
我運行的服務器被我們的一款 iPhone 游戲用於存儲分數的請求數量所殺死。 我的意思是服務器變得無響應。
我真的只知道足夠多的 MySQL/PHP 來解決這個問題,所以我在努力解決這個問題。 我確信這是一個可以優化的問題,因為我們有一個專用服務器。 我們每分鍾只處理 300 個請求。
基本上,我們檢查某人從他們的 iPhone 游戲中發布的分數(使用 SELECT)來查看他們是否有現有分數。 如果他們這樣做了,並且他們的新分數更好,我們執行 UPDATE,否則我們執行 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' AND fbuid = '$fbuid'"
$sql = "INSERT INTO $table(board, udid, fbuid, name, score, level, country) VALUES ('$board', '$udid', '$fbuid', '$name', '$score', '$level', $country')"
為了完整起見,這里是表的定義:
創建表
$table
(
id
int(11) 不是 NULL auto_increment,
board
tinyint(4) 不是 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,
主鍵(id
),
KEYscoreidx
(score
),
鍵udididx
(udid
),
鍵fbuididx
(fbuid
),
KEYboardidx
(board
),
KEYlevelidx
(level
),
KEYcountryidx
(country
)
) 引擎=MyISAM 默認字符集=latin1
我目前使用以下命令從 PHP 連接到 MySQL 服務器:
$conn = mysql_pconnect(DB_HOST,DB_USER,DB_PASSWORD,MYSQL_CLIENT_INTERACTIVE);
但是以前使用過 msql_connect ,但沒有注意到它的改進。
任何關於我如何優化它的指針,或任何 web 頁面的鏈接都將非常感激。
MyISAM具有表鎖而不是InnoDB行鎖。 您可以創建表的副本,將引擎更改為InnoDB,並(在測試服務器上)使用mysqlslap
或類似的壓力測試工具測試負載。
另外,非常重要:
ALTER TABLE tablename ADD INDEX(board,name,udid,fbuid)
MySQL一次只能使用1個索引,所以當你總是查詢這個特定組合時,你的幾個“松散”索引並沒有那么好。
“MySQL對MyISAM,MEMORY和MERGE表使用表級鎖定,對BDB表使用頁級鎖定,對InnoDB表使用行級鎖定。”
http://dev.mysql.com/doc/refman/5.0/en/internal-locking.html
因此,每次更新時,完整表都會獲得鎖定。 您可能想切換到InnoDB。
您可以嘗試通過不對重復的主鍵進行選擇和更新進行優化。您需要一個主鍵,如電子郵件地址或其他東西。
$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'";
==對不起語言錯誤,但可以用文本文件來完成。 如果是傳入的連接數,你可能需要在游戲二進制文件中創建一個定時器單元來調用和接收以查找是否必須重試,同時持有從 web 服務器交換回游戲的令牌號數據(隊列上的數據作業,例如 EJB)。 當每個步驟都被驗證發生時,游戲中的計時器和等待過程可以停止。 在 web 服務器 ServletContext 中持久化 object 以存儲帶有 Id 令牌的作業,以及一個包含令牌和作業完成狀態的鏡像列表。 這樣,MySQL 的網絡服務器可以簡單地逐個處理列表,直到它被游戲請求和輸入例如 hashmao 列表的數據重新觸發。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.