Оптимизация трекера — Начало !

Думаю пора приступать и начнем с самых малых азов .

Сегодня мы будем приручать запрос ,  который постоянно долбит базу ,  сообщая ип и время последнего визита пользователя на сайте  .

Запрос этот выглядит следующим образом :

sql_query("UPDATE users SET last_access = ".sqlesc(get_date_time()).", ip = ".sqlesc($ip)." WHERE id=" . $row["id"]);// or die(mysql_error());

То есть , при переходе юзера по страницам , система каждый раз долбит базу одним и тем же запросом —
Вот посмотри , пользователь три секунды назад был тут и ип у него такой . Нахер оно нам надо ?

Сократим время обновления базы о юзере , сделаем это при помощи сессий ( $_SESSION ).  Обновление данных проходит раз в 5 минут , что с экономит пару (а то и сотню) тысяч запросов в сутки , таким образом снимим нагрузку на mysql .

Что нам для этого надо ? Пишем код , который будет добавлять в сессию время последнего визитата пользователя и обновления базы данных , затем по истечению 5 минут , если пользователь все еще активно рыскает по сайту то по истечению установленого времени  разрешаем обновить данные в базе .

Код выглядит следующим образом :

if((!isset($_SESSION['last_access'])) or ($_SESSION['last_access'] < time() - 300)){
	$_SESSION['last_access'] = time();
	@sql_query("UPDATE LOW_PRIORITY users SET last_access = ".sqlesc(get_date_time()).", ip = ".sqlesc($ip)." WHERE id=" . $row["id"]);// or die(mysql_error());
	}

Что мы тут видим ?!

Проверка существует ли сессия и когда она была обновлена последний раз . 300 это время в секундах , они же 5 минут , я считаю что это оптимальный вариант .

if((!isset($_SESSION['last_access'])) or ($_SESSION['last_access'] < time() - 300))

Далее , если даже сессии не существует , то мы ее создадим и укажем в ней время обновления

$_SESSION['last_access'] = time();

Ну и сам запрос в базу данных на обновление информации о юзвере .

@sql_query("UPDATE LOW_PRIORITY users SET last_access = ".sqlesc(get_date_time()).", ip = ".sqlesc($ip)." WHERE id=" . $row["id"]);// or die(mysql_error());

Так же запрос немного модифицирован , к команде обновления UPDATE добавлен ключ LOW_PRIORITY . Что это ?

Если указывается ключевое слово LOW_PRIORITY, то выполнение данной команды UPDATE задерживается до тех пор, пока другие клиенты не завершат чтение этой таблицы.

Вот в принципе и все .

Если кто то имеет более оптимальный вариант , пишите .
В разработке кода мне помог reketir , за что ему отдельное спасибо .

Оптимизация трекера — Начало !: 50 комментариев

  1. Gilo

    Здравствуйте уважаемый мистем WEBNET!
    На сколько я понел нужно прописать это:

    if((!isset($_SESSION[‘last_access’])) or ($_SESSION[‘last_access’] < time() — 300)){
    $_SESSION['last_access'] = time();
    @sql_query("UPDATE LOW_PRIORITY users SET last_access = ".sqlesc(get_date_time()).", ip = ".sqlesc($ip)." WHERE id=" . $row["id"]);// or die(mysql_error());
    }

    В функшионс просто, а с тем запросом не чего не делать?

  2. webnet Автор записи

    Заменить тот запрос , на этот код . В файлике /include/functions.php

  3. Hannnn

    webnet а если у мня вот так стоит переделывать как ты советуешь?

    $updateset = array();
    if ($ip != $row[‘ip’])
    $updateset[] = ‘ip = ‘. sqlesc($ip);
    if (strtotime($row[‘last_access’]) < (strtotime(get_date_time()) — 300))
    $updateset[] = 'last_access = ' . sqlesc(get_date_time());

    if (count($updateset))
    sql_query("UPDATE LOW_PRIORITY users SET ".implode(", ", $updateset)." WHERE id=" . $row["id"]);// or die(mysql_error());
    $row['ip'] = $ip;

  4. webnet Автор записи

    если ты изменишь свой код полностью на этот , то проблем с работо-способностью у тебя не будет .

  5. Wolverine

    Кстати, спасибо большое)

    На 1 запрос меньше и нагрузка упала конкретно.

  6. Wolverine

    Ой бля**)))

    я ху**ю написал, то вообще у меня ошибка была)))) еще раз извиняюсь.

  7. Wolverine

    а для других запросов $_SESSION можно использовать?

  8. webnet Автор записи

    Смотря для каких ?!
    Сильно увлекаться идеей тоже не надо . Не надо сразу нападать и все пихать на сессии .
    Аналогичная ситуация была с файловым кешем , как только научились , так сразу же давай все пихать в кеш .

  9. Wolverine

    Под вот такой запрос, можно?

    $sql = «SELECT torrents.name, torrents.hide, torrents.poster AS poster, torrents.descr, torrents.id, torrents.comments, torrents.leechers, torrents.seeders, torrents.free AS free, torrents.numratings, torrents.ratingsum, IF(torrents.numratings < $minvotes, NULL, ROUND(torrents.ratingsum / torrents.numratings, 1)) AS rating, visible, category FROM torrents LEFT JOIN categories ON torrents.category = categories.id WHERE ontop='yes' ORDER BY id DESC $limit";

  10. webnet Автор записи

    :mrgreen: спасибо , посмеялся от души .

    Нет , нельзя !

  11. Gilo

    webnet, а можно в сессии взять запрос SELECT uri FROM stylesheets WHERE id = 6 , а то он тоже мозги мозолит на каждой стр … Подскажи как плиз

  12. Hannnn

    все пасиб сделал как ты сказал особо изменений не заметил но кода стало меньше =)

  13. webnet Автор записи

    :mrgreen: успакойся . В след посте напишу что с ними делать .

  14. m_M

    [2] => 0.000635147094727 [UPDATE sessions SET sid = », uid = 1, username = ‘!’, class = 6, ip = », time = 1266526563, url = ‘/?pgt’, useragent = ‘Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2) Gecko/20100115 Firefox/3.6 WebMoney Advisor’ WHERE sid = »]

    Запрос непропал?

    Как я понял заменить нада етот кусок

    sql_query(«UPDATE users SET last_access = «.sqlesc(get_date_time()).», ip = «.sqlesc($ip).» WHERE id=» . $row[«id»]);// or die(mysql_error());
    $row[‘ip’] = $ip;

  15. Gilo

    Дядь webnet , а когда будет твой следующий пост? Я жду не дождусь уже.. Поскорее бы

  16. Hannnn

    ну когда там уже будет следующая оптимизация или защи? ❓ 🙄 😆

  17. Ninja

    А зачем вообще оптимизировать этот запрос?
    у меня при 200 000 юзерах, нагрузка от него всего: 0.00036

    Так что, по мне так, но это бессмысленно! ^_~
    Избавляться надо только от тяжёлых запросов, а такие можно и оставить.

  18. webnet Автор записи

    и что ты предлагаешь ?
    Лезть каждому в код трекера , искать тяжелые запросы и оптимизировать их ?
    Буду выкладывать коды , при помощи которых можно ускорить дефолтный движок в разы .

  19. Wolverine

    Webnet, можешь выложит небольшой список запросов к которым можно сессии прикрутить?
    Пожалуйста :mrgreen:

  20. Reliser

    Спасибо за код, но так же, как и после кода Юны в чате не показывается онлайн. Уважаемый, не подскажите решение проблемы?

  21. vlackconf

    if((!isset($_SESSION[‘last_access’])) or ($_SESSION[‘last_access’] < time() — 300)){
    $_SESSION['last_access'] = time();
    @sql_query("UPDATE LOW_PRIORITY users SET last_access = ".sqlesc(get_date_time()).", ip = ".sqlesc($ip)." WHERE id=" . $row["id"]);// or die(mysql_error());
    }
    это в functions.php должно быть? или в ставить надо?

  22. Reliser

    vlackconf, этой функцией заменяешь запрос в functions.php

  23. Reliser

    И кто подскажет, как восстановить «погибший» онлайн в чате после этой функции?

  24. webnet Автор записи

    Емае , что же вы такие глупые . Измени время , по которому выберает пользователей .

  25. Reliser

    webnet, в смысле? Ты предлагаешь изменить время в этой функции? А что от этого изменится? онлайн все равно показывать не будет…

  26. vlackconf

    так нет подобного запроса в functions.php.

  27. webnet Автор записи

    я предлагаю изменить время выборки онлайн для чата .
    Если эта функция обновляется раз в 10 минут , то в чате выборка должна идти на раз в 15 минут . ну или как нибудь так .

  28. den_in

    По лазив по форуму http://bit-torrent.kiev.ua
    нашел другой вариант оптимизации этого запроса от Yuna

    $updateset = array();

    if ($ip != $row[‘ip’])
    $updateset[] = ‘ip = ‘. sqlesc($ip);
    if (strtotime($row[‘last_access’]) < (strtotime(get_date_time()) — 300))
    $updateset[] = 'last_access = ' . sqlesc(get_date_time());

    if (count($updateset))
    sql_query("UPDATE LOW_PRIORITY users SET ".implode(", ", $updateset)." WHERE id=" . $row["id"]);// or die(mysql_error());
    $row['ip'] = $ip;

    можно узнать в чем отличие?и какой из вариантов будет лучше?

  29. bot

    Запросов не уменьшится на странице, а просто снизится нагрузка на трекер?

  30. NarK

    Ммм, а где это все прописывать и уберать? Прошу прощение за убого нубский вопрос.

Комментарии запрещены.