Оптимизация запросов и своя функция doquery ()

Sergiy

Новичок
Оптимизация запросов и своя функция doquery ()

Работаю над скриптом браузерной игры.
Уже полностью рабочий, но возникает перегрузка обращений к БД.
Возможно, это из-за частого использования собственной функции, обращающейся к БД?
Вот она -
<?
function doquery($query, $table, $fetch = false){
global $numqueries,$link,$debug,$ugamela_root_path;
require($ugamela_root_path.'config.php');

if(!$link)
{$link = mysql_connect($dbsettings["server"], $dbsettings["user"],
$dbsettings["pass"]) or
$debug->error(mysql_error()."<br />$query","SQL Error");

mysql_select_db($dbsettings["name"]) or $debug->error(mysql_error()."<br />$query","SQL Error");
mysql_query("SET NAMES cp1251");
echo mysql_error();}

$sql = str_replace("{{table}}", $dbsettings["prefix"].$table, $query);
$sqlquery = mysql_query($sql) or
$debug->error(mysql_error()."<br />$sql<br />","SQL Error");

unset($dbsettings);
$numqueries++;
$arr = debug_backtrace();
$file = end(explode('/',$arr[1]['file']));
$line = $arr[1]['line'];
$debug->add("<tr><th>Query $numqueries: </th><th>$query</th><th>$file($line)</th><th>$table</th><th>$fetch</th></tr>");

if($fetch)
{$sqlrow = mysql_fetch_array($sqlquery);
return $sqlrow;
}else{return $sqlquery;}}
?>

Во всём скрипте в дальнейшем используется функция doquery и для чтения и для записи в БД (кстати она это действительно позволяет?).

Например $CurrentPlanet = doquery("SELECT * FROM {{table}} WHERE `id` = '". $user['current_planet'] ."';", 'planets', true);

Будет ли оптимизацией замена её на mysql_fetch для чтения?
И что тогда будет, если не отключаться от БД ?
Постоянное соединение юзера?
А при закрытии браузера он отсоединится автоматически?
Возможно ли, что при постоянных соединениях ошибка запроса в некоторых скриптах может заставить базу лежать долго?
 

Фанат

oncle terrible
Команда форума
чувак, ты вообще не понимаешь, что делаешь.
тебе не игры писать, а детский сад закончить, хотя бы с тройками.

Что за бредовые вопросы?
ты не знаешь, позволяет ли твоя функция писать в БД?
при чем здесь mysql_fetch_array? как она что-то ускорит, если она у тебя и так используется?
при чем здесь отключение от бд? что значит "тогда"? А сейчас ты отключаешься? А в документации нельзя прочитать, что будет?

и что такое, блин, "перегрузка обращений к БД"? Кирпичи она у тебя грузит?
 

Sergiy

Новичок
1) Я привёл пример - $CurrentPlanet = doquery("SELECT * FROM {{table}} WHERE `id` = '". $user['current_planet'] ."';", 'planets', true);
В $CurrentPlanet таким образом читается строка из таблицы 'planets'. Спрашиваю, будет ли лучше читать эту строку стандартной функцией чтения из БД, не применяя эту doquery()
Если ты заметил в ней происходит коннект/дисконнект к БД и от БД. Может, это тормозит работу скрипта?
2) mysql_fetch_array может заменить, имхо, применение этой функции, при этом будет использоваться постоянное соединение.
3) перегрузка - это когда хостер отключает моих пользователей от БД из-за слишком большого количества одновременных запросов
 

Фанат

oncle terrible
Команда форума
дааааа. каша у тебя в голове едрёная.
будет ли лучше читать эту строку стандартной функцией чтения из БД, не применяя эту doquery()
да какая хрен разница?
Если ты заметил в ней происходит коннект/дисконнект к БД и от БД.
я заметил, что коннект происходит только один раз.
дисконнекта не заметил вообще
перегрузка - это когда хостер отключает моих пользователей от БД из-за слишком большого количества одновременных запросов
уже лучше. хотя с твоими талантами я не удивлюсь, что проблема совсем другая.
ты можешь как можно более точно описать проблему?
решить ей самостоятельно у тебя все равно не получится, если все, что ты придумал - это менять одну функцию на другую. очень толковый подход к решению проблем. очень.
поэтому постарайся не прибавляя от себя вообще ничего привести здесь либо письмо хостера, либо симптомы.

-~{}~ 01.06.08 15:50:

и при чем здесь оптимизация запросов?
 

Sergiy

Новичок
Человек 30 примерно работали с базой одновременно. Периодически хостер отключает доступ к БД.
#1226 - User \'xngame152\' has exceeded the \'max_user_connections\' resource (current value: 20)

Скрипт этот мой - браузерная игра.
Вся информация об игроках в БД, а так как контактируют игроки друг с другом часто, и обмениваются информацией, то часто обновляются данные в БД. Обращения к БД видимо, так криво написаны, что 30 человек в онлайне уже могут упереться в лимит, хотя на других сайтах моего хостера ЗНАЧИТЕЛЬНО больше пользователей, но они почему-то не упираются в лимит.

Большинство обращений к БД идёт через эту функцию. Например, даже удаление строки из таблицы FLEETS выглядит так -
doquery ("DELETE FROM {{table}} WHERE `fleet_id` = " . $FleetRow["fleet_id"], 'fleets');
Письмо хостера - Нельзя делать как вы - при каждом запросе подключаться к базе... И вам надо не постоянные соединения создавать, а на странице 1 раз подключаться, делать свою кучу запросов, и в конце - отключаться.
Но я не знаю, может быть проблема перегрузки не только в этом.
Как исправить ситуацию, подскажите, пожалуйста.
 

zerkms

TDD infected
Команда форума
тебе хостер уже ответил на твой вопрос
включай мозг

-~{}~ 02.06.08 16:51:

кстати, а что будет если в запросе будет участвовать подстрока {{table}} ? :))
 

Фанат

oncle terrible
Команда форума
Sergiy
Кто-то из вас - дурак. Либо ты, либо хостер.
Либо у нас неполная информация.

Судя по тексту функции, которую ты привел здесь, никто при каждом запросе не подключается к базе.
И соединения создаются не постоянные.
Так что или у тебя не такая функция используется, либо хостер не понимает, о чем говорит.

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

MSW

Новичок
Насколько я понимаю это вот и есть коннект к бд:
PHP:
if(!$link)
{$link = mysql_connect($dbsettings["server"], $dbsettings["user"],
$dbsettings["pass"]) or
$debug->error(mysql_error()."<br />$query","SQL Error");

mysql_select_db($dbsettings["name"]) or $debug->error(mysql_error()."<br />$query","SQL Error");
mysql_query("SET NAMES cp1251");
echo mysql_error();}
*****
я думаю что люди приходят на форум для того чтоб обмениваться опытом и получать знания из опыта других.
Вы ведь тоже не родились гуру-программистом, это всё это приходит с опытом, и все с чегото начинали.
я сам не сильно знаю php, поэтому и спрашиваю у знающих людей, в надежде что кто-то подскажет.
А получается что вместо помощи наталкиваешься на грубость, что не создаёт положительного впечатления о пользователе который таким способом "пытается помочь".
 

Фанат

oncle terrible
Команда форума
MSW
верно. получать знания из опыта других. а не лепет таких же новичков.
 

zerkms

TDD infected
Команда форума
MSW
Насколько я понимаю
в том то и дело, что ты не очень понимаешь. этот код не может:
1. плодить кучу коннектов
2. делать постоянные соединения

вывода два:
1. врёт тредстартер
2. врёт админство провайдера
 

MSW

Новичок
*****
все были новичками.
и я сейчас тоже являюсь новичком.

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

zerkms
да, дело в том что не сильно понимаю :)

просто такая ситуация - в некоторых файлах идёт до 10-ти вызовов функции doquery, вот в такой ситуации - могут плодиться куча подключений?
вот поэтому и созрел вопрос: если в начале таких файлов где идёт насколько вызовов этой функции doquery - сделать так что при первом обращении коннектиться а последующие обращения уже не коннектиться к БД снова, а используют прошлое подключение, а в конце просто отключаться от БД.
Вот тут ещё вопрос: отключение от БД - сильно критично? и нужно ли оно?
 

zerkms

TDD infected
Команда форума
в некоторых файлах идёт до 10-ти вызовов функции doquery, вот в такой ситуации - могут плодиться куча подключений?
нет, не может. даже если убрать $link, который ему, кстати, абсолютно не нужен, коннект всегда будет один.

отключение от БД - сильно критично? и нужно ли оно?
нет, после выполнения скрипта оно закроется само.
 

MSW

Новичок
тоесть в такой ситуации:
PHP:
doquery ( "DELETE FROM {{table}} WHERE `message_sender` = '" . $UserID . "';", 'messages' );
doquery ( "DELETE FROM {{table}} WHERE `message_owner` = '" . $UserID . "';", 'messages' );
doquery ( "DELETE FROM {{table}} WHERE `owner` = '" . $UserID . "';", 'notes' );
doquery ( "DELETE FROM {{table}} WHERE `fleet_owner` = '" . $UserID . "';", 'fleets' );
doquery ( "DELETE FROM {{table}} WHERE `id_owner1` = '" . $UserID . "';", 'rw' );
doquery ( "DELETE FROM {{table}} WHERE `id_owner2` = '" . $UserID . "';", 'rw' );
doquery ( "DELETE FROM {{table}} WHERE `sender` = '" . $UserID . "';", 'buddy' );
doquery ( "DELETE FROM {{table}} WHERE `owner` = '" . $UserID . "';", 'buddy' );
doquery ( "DELETE FROM {{table}} WHERE `user` = '" . $UserID . "';", 'annonce' );
doquery ( "DELETE FROM {{table}} WHERE `id` = '" . $UserID . "';", 'users' );
doquery ( "DELETE FROM {{table}} WHERE `id` = '" .  id_owner . "';", 'planets' );
при первом вызове doquery - произойдёт подключение к базе данных, а при второй и последующих doquery - заново подключатся к БД не будет?
или в каждой из выше приведённых строк будет снова подключаться к БД?
 

zerkms

TDD infected
Команда форума
MSW
ты притворяешься? уже дважды минимум было сказано - что нет, повторного подключения не будет.

повторного подключения не будет
 

MSW

Новичок
zerkms
спасибо, это какраз и интересовало.
значит проблема в другом... будем искать :)
 

Sergiy

Новичок
Как включить журналирование запросов мускула, чтобы запросы в файл писались, а я его открыл и посмотрел, когда там они пойдут массово?
 

Фанат

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

zerkms

TDD infected
Команда форума
Sergiy
в конфиге мускула

-~{}~ 02.06.08 19:21:

zerkms
"max_user_connections" не будет сгенерено большим числом запросов, имхо
 

Фанат

oncle terrible
Команда форума
zerkms
если запросы будут исполняться подолгу, то почему нет?
причина, как мы выяснили - не в количестве коннектов. значит - из-за тормозов, скорее всего, разные скрипты накладываются. отсюда и переконнект.

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

MSW

Новичок
как этот столбик можна сложить в один? :)

Если напрямую запрос в бд - то думаю что так:
PHP:
DELETE FROM messages, notes, fleets, rw, buddy, annonce, users, planets WHERE messages.message_sender ='$UserID' OR messages.message_owner = '$UserID' OR notes.owner ='$UserID' OR fleets.fleet_owner='$UserID' OR rw.id_owner1='$UserID' OR rw.id_owner2='$UserID' OR buddy.sender='$UserID' OR buddy.owner='$UserID' OR annonce.user='$UserID' OR users.id='$UserID'
тогда php запрос будет таким?

PHP:
doquery ( "DELETE FROM {{table}} WHERE `messages.message_sender`='" . $UserID . "' OR `messages.message_owner`= '" . $UserID . "' OR `notes.owner`='" . $UserID . "' OR `fleets.fleet_owner`='" . $UserID . "' OR `rw.id_owner1`='" . $UserID . "' OR `rw.id_owner2`='" . $UserID . "' OR `buddy.sender`='" . $UserID . "' OR `buddy.owner`='" . $UserID . "' OR `annonce.user`='" . $UserID . "' OR `users.id`='" . $UserID . "';", 'messages', 'notes', 'fleets', 'rw', 'buddy', 'annonce', 'users', 'planets' );
но так не работат :) ругаеться на синтаксис, как ни странно
Подскажите, пожалуйста, где тут затаилась ошибка, кроме как в недостаточности мои знаний по этому вопросу :)

Это скрипт удаления юзеров которые не играют больше чем 35 дней, или тех кто установил в опциях удаление аккаунта, вот это подчищение таких строк.
выполняется каждый раз при обновлении статистики в игре. это примерно 2-6 раз в день, в зависимости от того кто насколько часто обновляет статистику, у меня она обновляеться на кроне каждые 4 часа
 
Сверху