Оптимизация (Шаг 1)

Статус
В этой теме нельзя размещать новые ответы.

AlexProWars

Старейшина
Репутация
90 / 129
Начнём курс оптимизации движка Хновы :)

В сети гуляет одна оптимизация обработки флотов. Так как она представляет собой чуш, предложу свой вариант. Я не буду выкладывать всё готовое, я расскажу по порядку как чё делать, чтобы вы могли понять.
Начнём с низов, а точнее с FlyingFleetHandler.php
Имеем код:

Код:
function FlyingFleetHandler (&$planet) {
    global $resource;

    doquery("LOCK TABLE {{table}}lunas WRITE, {{table}}rw WRITE, {{table}}errors WRITE, {{table}}messages WRITE, {{table}}fleets WRITE, {{table}}planets WRITE, {{table}}galaxy WRITE ,{{table}}users WRITE", "");

    $QryFleet   = "SELECT * FROM {{table}} ";
    $QryFleet  .= "WHERE (";
    $QryFleet  .= "( ";
    $QryFleet  .= "`fleet_start_galaxy` = ". $planet['galaxy']      ." AND ";
    $QryFleet  .= "`fleet_start_system` = ". $planet['system']      ." AND ";
    $QryFleet  .= "`fleet_start_planet` = ". $planet['planet']      ." AND ";
    $QryFleet  .= "`fleet_start_type` = ".   $planet['planet_type'] ." ";
    $QryFleet  .= ") OR ( ";
    $QryFleet  .= "`fleet_end_galaxy` = ".   $planet['galaxy']      ." AND ";
    $QryFleet  .= "`fleet_end_system` = ".   $planet['system']      ." AND ";
    $QryFleet  .= "`fleet_end_planet` = ".   $planet['planet']      ." ) AND ";
    $QryFleet  .= "`fleet_end_type`= ".      $planet['planet_type'] ." ) AND ";
    $QryFleet  .= "( `fleet_start_time` < '". time() ."' OR `fleet_end_time` < '". time() ."' );";
    $fleetquery = doquery( $QryFleet, 'fleets' );

    while ($CurrentFleet = mysql_fetch_array($fleetquery)) {
        switch ($CurrentFleet["fleet_mission"]) { и т.д.

Полезем в common.php. Имеем код:

Код:
        $_fleets = doquery("SELECT * FROM {{table}} WHERE `fleet_start_time` <= '".time()."';", 'fleets');
        while ($row = mysql_fetch_array($_fleets)) {
            $array                = array();
            $array['galaxy']      = $row['fleet_start_galaxy'];
            $array['system']      = $row['fleet_start_system'];
            $array['planet']      = $row['fleet_start_planet'];
            $array['planet_type'] = $row['fleet_start_type'];

            $temp = FlyingFleetHandler ($array);
        }

$_fleets = doquery("SELECT * FROM {{table}} WHERE `fleet_end_time` <= '".time()."';", 'fleets'); //  OR fleet_end_time <= ".time()
        while ($row = mysql_fetch_array($_fleets)) {
            $array                = array();
            $array['galaxy']      = $row['fleet_end_galaxy'];
            $array['system']      = $row['fleet_end_system'];
            $array['planet']      = $row['fleet_end_planet'];
            $array['planet_type'] = $row['fleet_end_type'];

            $temp = FlyingFleetHandler ($array);
        }

В этом кусочке мы и будем делать оптимизацию. В common.php мы видим почти 2 одинаковых куска кода, почему бы не соединить 2 запроса в 1, результат будет тем же, но на один запрос к бд меньше:

Код:
$_fleets = doquery("SELECT * FROM {{table}} WHERE `fleet_start_time` <= '".time()."' OR fleet_end_time <= '".time()."';", 'fleets');
        while ($row = mysql_fetch_array($_fleets)) {
            $array                = array();
            $array['galaxy']      = $row['fleet_start_galaxy'];
            $array['system']      = $row['fleet_start_system'];
            $array['planet']      = $row['fleet_start_planet'];
            $array['planet_type'] = $row['fleet_start_type'];

            $temp = FlyingFleetHandler ($array);
        }

Далее смотрим в FlyingFleetHandler.php и видим что при вызове функции у нас происходит ещё один запрос к бд. А смысл его? Мы ведь выбираем данные в common.php и сними можно работать и в функции, зачем по 100 раз брать одно и тоже. Так же там было при этой связке много лиших вызовов функциё и пустых запросов. Мож но также убрать блокировку таблиц (на любителя, я использовал постоянные соединения к бд, поэтому при ошибках бд зависала).
После чистки FlyingFleetHandler.php выглядит так:

Код:
function FlyingFleetHandler (&$CurrentFleet) {
    global $resource;

    doquery("LOCK TABLE {{table}}lunas WRITE, {{table}}rw WRITE, {{table}}errors WRITE, {{table}}messages WRITE, {{table}}fleets WRITE, {{table}}planets WRITE, {{table}}galaxy WRITE ,{{table}}users WRITE", "");

        switch ($CurrentFleet["fleet_mission"]) {

Ну а теперь подчистим common.php от ненужных массивов и переменных

Код:
$_fleets = doquery("SELECT * FROM {{table}} WHERE `fleet_start_time` <= '".time()."' OR fleet_end_time <= '".time()."';", 'fleets');
        while ($row = mysql_fetch_array($_fleets)) {
             FlyingFleetHandler ($array);
        }

Вот такая мини оптимизация, но это не предел. Завтра я распишу как это можно ещё оптимизировать, причем существенно.

P.S. В коде могут быть маленькие синтаксические ошибочки так как это не готовое решение, а описание пути достижения результата.

Спасибку не забываем.
 
Маленькая неточность:
Код:
FlyingFleetHandler ($array);
заменить на
Код:
FlyingFleetHandler ($row);
Писал с ходу, неувидел :D
 
Такс, продолжим. Из предъидущего шага мы получили на выходе оптимизированный код:
Код:
$_fleets = doquery("SELECT * FROM {{table}} WHERE `fleet_start_time` <= '".time()."' OR fleet_end_time <= '".time()."';", 'fleets');
        while ($row = mysql_fetch_array($_fleets)) {
             FlyingFleetHandler ($row);
        }
Он не являетсо окончательно оптимизированным, так как запрос
Код:
$_fleets = doquery("SELECT * FROM {{table}} WHERE `fleet_start_time` <= '".time()."' OR fleet_end_time <= '".time()."';", 'fleets');
выбирает нам:
--- Все флоты достигшие цели, но не вернувшиеся
--- Все флоты находящиеся на орбите на удержании и экспедициях
А это дополнительные строки из бд и бессмысленные вызовы функций.

Попробуем упростить ( :) не в плане размера) запрос выбрав то что необходимо для расчётов, а именно условие состоящее из 3 частей:
--- Флот который прилетел.
Код:
(`fleet_start_time` <= ".time()." AND `fleet_mess` = 0)
--- Флот которы окончил удержание или экспедицию.
Код:
(`fleet_end_stay` <= ".time()." AND `fleet_mess` > 1 AND `fleet_end_stay` != 0)
--- Флот который прилетел домой.
Код:
(`fleet_end_time` < ".time()." AND `fleet_mess` != 0)

В итоге получится такой коварный запросец:
Код:
    $_fleets = doquery("SELECT * FROM {{table}} WHERE (`fleet_start_time` <= ".time()." AND `fleet_mess` = 0) OR (`fleet_end_stay` <= ".time()." AND `fleet_mess` > 1 AND `fleet_end_stay` != 0) OR (`fleet_end_time` < ".time()." AND `fleet_mess` != 0);", 'fleets');

Это избавит вас от выборки излишних данных и бесполезных вызовов функций.

P.S. Могу посоветовать побаловаться с конструкцией LIMIT, может помоч после частых остановок игры, когда на первого клиента приходится обработка большей части флотов. Но если мало народу играет возможны задержки флота.

В следующем шаге расскажу вам как убрать бесполезные вызовы на обработку флотов.

Спасибку не забываем.
 
P.S: оптимизация не для екстрима. а для других версий.
Обсуждение ели нужно то в отдельной теме, но попробуйте разобраться сами...
Автора не видел давно.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху