lundi 27 juin 2016

MySQL/PHP Optimization - Poins based on client's data

I need to optimize this. PHP:

$time_start = microtime(true); 
$servername = "127.0.0.1";
$username = "test";
$password = "test";
$dbname = "test";
//SQL prefix
$prefix = "test_";
$mysqli = new mysqli($servername, $username, $password, $dbname);

if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

$gamehighestrecords = array();

function GetHighestRecord($game) {
    global $gamehighestrecords, $mysqli, $prefix;

    if (isset($gamehighestrecords[$game])) {
        return $gamehighestrecords[$game];
    } else {
        $sql = $mysqli->query("SELECT rank FROM {$prefix}main_records WHERE game='{$game}' ORDER BY rank DESC LIMIT 1;");
        $res = $sql->fetch_row();
        $gamehighestrecords[$game] = $res[0];
        return $gamehighestrecords[$game];
    }
}

$sql = $mysqli->query("SELECT auth FROM test_player_data");
while ($res = $sql->fetch_array()) {
    $rsql = $mysqli->query("SELECT * FROM test_records WHERE auth='{$res["auth"]}'");

    $points = 0;

    while ($records = $rsql->fetch_array()) {
        $totalrank = GetHighestRecord($records["game"]);
        $rank = $records["rank"];

        if ($totalrank == 0) continue;
        if ($rank == 0) continue;

        $multiplier = 7500;
        $points += (((1 - ($rank / $totalrank))) * $multiplier);
    }

    $mysqli->query("UPDATE test_player_data SET points={$points} WHERE auth='{$res["auth"]}'");
}

$time_end = microtime(true);
$execution_time = ($time_end - $time_start);
//execution time of the script
echo '<b>Total Execution Time:</b> '.$execution_time.' Seconds';

and the mysql structures:

== Table structure for table test_player_data

|------
|Column|Type|Null|Default
|------
|//**id**//|int(11)|No|
|**auth**|varchar(32)|No|
|points|float|No|
|rank|int(11)|No|

.

== Table structure for table test_main_records

|------
|Column|Type|Null|Default
|------
|//**id**//|int(11)|No|
|**auth**|varchar(32)|No|
|**game**|varchar(128)|No|
|time|float|No|
|rank|int(11)|No|

test_player_data has ~3k records, test_main_records has ~6k records. It takes about 0.7seconds to execute the php script ( Total Execution Time: 0.6869421005249 Seconds ). The tables will be getting much larger and 0.7 seconds just won't cut it. On average, a new record will be inputted/changed every minute. And I will need to recalculate the points then. I was thinking of updating only records that had a record in that "game" that got updated, but this will be in the thousands later on.

id is primary, auth/game are unique.

I hope I am making sense here.

Also, I know my code is horrendous. This is just "proof of concept".

Aucun commentaire:

Enregistrer un commentaire