我有一个我用PHP / MYSQL和FBJS / AJAX编写的Facebook应用程序。该应用程序是Rails Across Europe,可以在http://apps.facebook.com/rails_across_europe找到(请注意,它确实需要访问您的FB数据)。如果您想查看应用程序操作的截屏视频,可以在http://screenr.com/TZR和http://screenr.com/sZR(每个截屏视频约3分钟)进行操作。
问题是对用户输入的响应非常慢。我不确定是什么原因导致这个性能瓶颈。我对性能优化没有任何经验,这就是为什么我会请求你的帮助。我认为瓶颈可能是以下任何一个方面:
关于我的网络托管,我使用的是A2 Hosting共享托管帐户。我不确定这种类型的Web主机是否能够处理我的应用程序所需的密集型数据库和用户活动,但这是我能负担得起的。如果这可能是我的性能问题的根源,请告诉我。
为了帮助确定性能问题的根源,我提供了一些源代码。第一个是SQL查询,第二个是AJAX调用。
列车运动似乎是最慢的运行,所以我将以此为例。我意识到这是一个非常长的代码示例,但除非我提交整个上下文供您审阅,否则我不知道有谁可以帮助我。这是PHP / MYSQL代码:
MoveTrain.php
public function moveTrain($destCityId) {
require_once 'Train.php';
$trainModel = new Train();
require_once 'Route.php';
$routeModel = new Route();
$userNamespace = new Zend_Session_Namespace('User');
$gamePlayerId = $userNamespace->gamePlayerId;
$trainData = $trainModel->getTrain($gamePlayerId);
$originCityId = $trainData['origin_city_id'];
$destChanged = false;
if ( $destCityId != $trainData['dest_city_id'] ) {
$originCityId = $trainData['dest_city_id'];
$destChanged = true;
}
$routeResp = $routeModel->getPlayerRouteIdByCityIds($gamePlayerId, $originCityId, $destCityId);
$routeId = $routeResp['route_id'];
$trainRow = array();
// if route is invalid OR if destination city has not changed and train has arrived,
// bypass train movement
if($routeResp['error_msg'] == 'SUCCESS' || ($routeResp['error_msg'] == 'ROUTE_NOT_OWNED' && !$destChanged)) {
if((!$destChanged && $trainData['status'] == 'ENROUTE') ||
($destChanged && $trainData['status'] == 'ARRIVED')) {
$routeData = $routeModel->getRouteByCityIds($originCityId, $destCityId);
$unitsToDestination = 0;
$trainRow['direction'] = $routeModel->getRouteTravelDirection($originCityId, $destCityId); //+
// if traveling to a new city destination and traveling negative then train track unit
// is equal to route track unit count (because train is at the end of a new route)
switch ($trainRow['direction']) {
case '+':
if($destChanged && $trainData['status'] == 'ARRIVED') {
$trainData['track_unit'] = 0;
}
$unitsToDestination = $routeData['track_unit_count'] - $trainData['track_unit'];
break;
case '-':
if($destChanged && $trainData['status'] == 'ARRIVED') {
$trainData['track_unit'] = $routeData['track_unit_count'];
}
$unitsToDestination = $trainData['track_unit'];
break;
default:
break;
}
// 2. Move the train
$unitsToDestination = $unitsToDestination - $trainData['track_units_remaining'];
$trackUnitsRemaining = 0;
$trainArrived = false;
// Note that I changed from < to <=
if ( $unitsToDestination <= 0) {
// Went too far or arrived.
$trackUnitsRemaining = abs($unitsToDestination);
$trackUnit = $routeData['track_unit_count'];
if($trainRow['direction'] == '-') {
$trackUnit = 0;
}
$trainArrived = true;
} else {
// Did not reach destination
$trackUnitsRemaining = 0;
switch ( $trainRow['direction'] ) {
case '+':
$trackUnit = $routeData['track_unit_count'] - $unitsToDestination;
break;
case '-':
$trackUnit = $unitsToDestination;
break;
default:
break;
}
}
// 3. Save changes carefully.
$trainRow['route_id'] = $routeId;
$trainRow['origin_city_id'] = $originCityId;
$trainRow['dest_city_id'] = $destCityId;
$trainRow['track_unit'] = $trackUnit; //5
$trainRow['track_units_remaining'] = $trackUnitsRemaining; //2
// $trainArrived = ($trackUnit == 0 || $trackUnit == $routeData['track_unit_count']);
$trainRow['status'] = ($trainArrived) ? 'ARRIVED' : 'ENROUTE';
$trainRow['date_last_used'] = date('Y-m-d H:i:s');
//$trainId = $trainModel->getTrainId($gamePlayerId);
$where = $trainModel->getAdapter()->quoteInto('id = ?', $trainData['id']);
$trainModel->update($trainRow, $where);
} else {
$trainRow = $trainData;
}
}
return $trainRow;
}
Train.php:
public function getTrain($gamePlayerId) {
$sql = $this->getAdapter()->quoteInto("SELECT gp.player_number, t.* FROM train t, game_player gp WHERE t.`game_player_id` = ?", $gamePlayerId)
. ' AND gp.id = t.game_player_id;';
$stmt = $this->getAdapter()->query($sql);
$train = $stmt->fetchAll();
return $train[0];
}
Route.php:
public function getPlayerRouteIdByCityIds($gamePlayerId, $cityId1, $cityId2) {
$resp = array('route_id' => null, 'error_msg' => 'INVALID_ROUTE');
$where = $this->getAdapter()->quoteInto('(city_id_1 = ?', $cityId1)
. $this->getAdapter()->quoteInto(' AND city_id_2 = ?)', $cityId2)
. $this->getAdapter()->quoteInto(' OR (city_id_1 = ?', $cityId2)
. $this->getAdapter()->quoteInto(' AND city_id_2 = ?)', $cityId1);
$select = $this->select()->where($where);
$row = $this->fetchRow($select);
if($row) {
require_once 'PlayerRoute.php';
$playerRouteModel = new PlayerRoute();
if($playerRouteModel->isRouteOwned($row->id, $gamePlayerId)) {
$resp['route_id'] = $row->id;
$resp['error_msg'] = 'SUCCESS';
return $resp;
}
$resp['error_msg'] = 'ROUTE_NOT_OWNED';
}
return $resp;
}
public function getRouteByCityIds($cityId1, $cityId2) {
$db = $this->getAdapter();
$sql = 'SELECT * FROM route AS r'
. $db->quoteInto(' WHERE (r.city_id_1 = ?', $cityId1)
. $db->quoteInto(' AND r.city_id_2 = ?)', $cityId2)
. $db->quoteInto(' OR (r.city_id_1 = ?', $cityId2)
. $db->quoteInto(' AND r.city_id_2 = ?);', $cityId1);
$stmt = $db->query($sql);
$routeRow = array();
foreach($stmt as $row) {
$routeRow = $row;
}
if(count($routeRow) == 0) { return false; }
$sql = $db->quoteInto('SELECT track_unit_count FROM route_count WHERE id = ?', $routeRow['id']);
$stmt = $db->query($sql);
foreach($stmt as $row) {
$routeRow['track_unit_count'] = $row['track_unit_count'];
}
return $routeRow;
}
public function getRouteTravelDirection($startCityId, $endCityId) {
$routeData = $this->getRouteByCityIds($startCityId, $endCityId);
return ($routeData['city_id_1'] == $startCityId) ? '+' : '-';
}
PlayerRoute.php
public function isRouteOwned($routeId, $gamePlayerId) {
$where = $this->_db->quoteInto('route_id = ?', $routeId)
. $this->_db->quoteInto(' AND game_player_id = ?', $gamePlayerId);
$select = $this->select()->where($where);
$row = $this->fetchRow($select);
return (!$row) ? false : true;
}
我决定不提交FBJS / AJAX代码示例。也许我会将其作为另一个问题提交。感谢任何可以帮助我的人。
答案 0 :(得分:0)
修改my.conf以记录长查询并将时间设置得相当高(可能是5秒)。如果性能问题是一个mysql查询,你会在日志中看到它。