[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Слишком большое время обработки php+sql
Jekel
Здравствуйте, написал кодец, но время обработки у него 250+ ms ... проблемма в том, что каждых 100ms к нему за ответом обращается 'ajax'....надо php'шный код оптимизировать что-ли как-то...это реально тут сделать? Тупит из-за большого обьема БД...сейчас там 1500записей. Когда было 120 - не тупило(((
вобщем, помогите пожалуйста максимально оптимизировать код..
код:
$userdat = mysql_fetch_assoc(mysql_query("SELECT * FROM users WHERE id='".$_POST["plid"]."'")); 

$count = 0;

for ($y=$userdat["y"]-5; $y<=$userdat["y"]+5; $y++){
for ($x=$userdat["x"]-5; $x<=$userdat["x"]+5; $x++){
$data_map = mysql_fetch_assoc(mysql_query("SELECT * FROM map WHERE loc='".$userdat["loc"]."' AND x='".$x."' AND y='".$y."'"));
if($data_map["img"]!="" && $data_map["img"]!=NULL){
if($_SESSION["x".$count]!=$data_map["img"]){
$map.="<d".$count.">".$data_map["img"]."</d".$count.">";
$_SESSION["x".$count]=$data_map["img"];
}
}
else{
if($_SESSION["x".$count]!="0"){
$map.="<d".$count.">0</d".$count.">";
$_SESSION["x".$count]="0";
}
}

$count+=1;
}
}




Спустя 19 минут, 45 секунд (19.10.2010 - 15:08) arvitaly написал(а):
А чо он делает то

Спустя 1 час, 9 минут, 20 секунд (19.10.2010 - 16:17) Guest написал(а):
Никогда, никогда, никогда, НИКОГДА не помещайте SELECT запросы в циклы !!!

Спустя 2 минуты, 11 секунд (19.10.2010 - 16:19) Guest написал(а):
26 запросов к БД каждые 100 милисекунд = 260 запросов в секунду от одного юзера!

Бедный мускуль...

Спустя 49 минут, 41 секунда (19.10.2010 - 17:09) linker написал(а):
В таблице map обязательно необходимо автоинкрементное поле id.
if ($userdat = mysql_fetch_assoc(mysql_query("SELECT * FROM users WHERE id='".$_POST["plid"]."'")))
{
$count = 0;
$arr_x = array();
$arr_y = array();
for ($y=$userdat["y"]-5; $y<=$userdat["y"]+5; $y++)
{
$arr_y[] = $y;
for ($x=$userdat["x"]-5; $x<=$userdat["x"]+5; $x++)
$arr_x[] = $x;
}
$resource = mysql_query("SELECT * FROM `map` "
. "WHERE `loc` = '" . $userdat["loc"] . "' AND `x` IN (" . join(',', $arr_x) . ") AND `y` IN (" . join(',', $arr_y) . ")")
while($data_map = mysql_fetch_assoc($resource))
{
$session_name = "x" . $data_map['id'];
if (empty($data_map['img'])) continue;
if ($_SESSION[$session_name] != $data_map['img'])
{
$_SESSION[$session_name] = $data_map["img"];
$map .= "<d" . $data_map['id'] . ">" . $_SESSION[$session_name] . "</d" . $data_map['id'] . ">";
}
else
{
if ($_SESSION[$session_name])
{
$_SESSION[$session_name] = 0;
$map .= "<d" . $data_map['id'] . ">" . $_SESSION[$session_name] . "</d" . $data_map['id'] .">";
}
}
}
}


Спустя 4 часа, 48 минут, 25 секунд (19.10.2010 - 21:57) Jekel написал(а):
етить ты гений, идея супер) сейчас попробую. спасибо большое blink.gif

Спустя 30 минут, 24 секунды (19.10.2010 - 22:28) Jekel написал(а):
не работает...и ошибок нету...
пихаю в while alert и ничерта не алертит...$resource пустой походу huh.gif

Спустя 24 минуты, 30 секунд (19.10.2010 - 22:52) sergeiss написал(а):
И еще вопрос "на всякий случай": а есть индексы по нужным полям?

Спустя 9 минут, 43 секунды (19.10.2010 - 23:02) Jekel написал(а):
индексов нету)
вышепривиденный код выдает только 35 результатов

Спустя 9 минут, 28 секунд (19.10.2010 - 23:11) sergeiss написал(а):
Цитата (Jekel @ 19.10.2010 - 15:48)
Тупит из-за большого обьема БД...сейчас там 1500записей. Когда было 120 - не тупило(((

Цитата (Jekel @ 20.10.2010 - 00:02)
индексов нету)


Вот эти 2 цитаты говорят о том, что индексы надо сделать. Обязательно. 1500 записей - это "копейки" smile.gif Если правильные индексы сделаны, то и с миллионом записей сделать небольшую выборку будет легко. Но без индексов, как ты убедился, и с 1500 записей тормозить будет.

И учти, что наличие индексов не отменяет то, что выше было другими форумачанами написано. Насчет оптимизации кода и уменьшения количества выборок до разумного количества.

Спустя 51 минута, 42 секунды (20.10.2010 - 00:03) Jekel написал(а):
такого типа таблица...подскажешь как правильно сделать?
CREATE TABLE `map` (
`id` int NOT NULL AUTO_INCREMENT,
`loc` char(255) default NULL,
`x` int default NULL,
`y` int default NULL,
`img` char(255) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

сделал так, производительность поднялась...но хотелось бы чтобы работало быстрее):

CREATE TABLE `map` (
`id` int NOT NULL AUTO_INCREMENT,
`loc` char(255) default NULL,
INDEX i_loc(loc(20)),
`x` int(11) default NULL,
INDEX i_x(x),
`y` int(11) default NULL,
INDEX i_y(y),
`img` char(255) default NULL,
`about` longtext,
`wall` int(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

Спустя 2 часа, 57 минут, 35 секунд (20.10.2010 - 03:01) Jekel написал(а):
проверил на большой базе
в таблице 500.000 строк время обработки около 500ms
надо меньше 100ms ибо запросы на серв каждых 100мс поступают

linker, код работает не коректно, выдает не полный ответ...читает мало с базы( должно читать 121 строку, читает и выдает 35+-
сейчас он так выглядит

$userdat = mysql_fetch_assoc(mysql_query("SELECT * FROM users WHERE id='1'")); 

$count = 0;
$arr_x = array();
$arr_y = array();

for ($y=$userdat["y"]-5; $y<=$userdat["y"]+5; $y++){
$arr_y[] = $y;
for ($x=$userdat["x"]-5; $x<=$userdat["x"]+5; $x++){
$arr_x[] = $x;
}
}

$resource = mysql_query("SELECT * FROM `map` WHERE `loc` = 0 AND `x` IN (" . join(',', $arr_x) . ") AND `y` IN (" . join(',', $arr_y) . ")");

while($data_map = mysql_fetch_assoc($resource)){
$session_name = "x" . $count;
if (empty($data_map['img'])) continue;
if ($_SESSION[$session_name] != $data_map['img']){
$_SESSION[$session_name] = $data_map["img"];
$map .= "<d" . $count . ">" . $_SESSION[$session_name] . "</d" . $count . ">";
}else{
if ($_SESSION[$session_name]){
$_SESSION[$session_name] = 0;
$map .= "<d" . $count . ">" . $_SESSION[$session_name] . "</d" . $count .">";
}
}


$count++;
}

Спустя 6 часов, 6 минут, 18 секунд (20.10.2010 - 09:07) linker написал(а):
Для начала после запроса смотрим сколько реально отдает строк
echo mysql_num_rows($resource);
Должен отдать именно 121 запись, поправил код свой немного вот так
$arr_x = array();
$arr_y = array();
for ($y=$userdat["y"]-5; $y<=$userdat["y"]+5; $y++)
$arr_y[] = $y;
for ($x=$userdat["x"]-5; $x<=$userdat["x"]+5; $x++)
$arr_x[] = $x;
А вот дальше нужно смотреть логику, возможно я не совсем понял твою логику, а от сюда и косяк. Значится чтобы разобраться нужны ответы на следующие вопросы:
1. Поле img в таблице map может быть пустым?
2. Зачем при условии if($_SESSION["x".$count] != "0") обнуляется $_SESSION["x".$count]?

Спустя 3 часа, 21 минута, 47 секунд (20.10.2010 - 12:29) Jekel написал(а):
1. Может
2. если сессия равна нулю, дает ответ <d56>0</d56>, а в js условие...если 0, то divMap.style.backgroundImage = "none"; ))

Вот полный код js:
function getdata(){
var plid = document.getElementById("plid").value;
var XMLHttpRequestObject=false;if(window.XMLHttpRequest){XMLHttpRequestObject=new XMLHttpRequest();}else if(window.ActiveXObject){XMLHttpRequestObject=new ActiveXObject("Microsoft.XMLHTTP");}

if (XMLHttpRequestObject.readyState == 4 || XMLHttpRequestObject.readyState == 0){
XMLHttpRequestObject.open("POST", "serv/map.php");
XMLHttpRequestObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
XMLHttpRequestObject.onreadystatechange = function(){
if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200){
var xmlDoc = XMLHttpRequestObject.responseXML;
var xmlSed = xmlDoc.documentElement;
var xmlNum = xmlSed.childNodes.length;
var xmlGet;
for(xmlGet=0; xmlGet<xmlNum; xmlGet++){
var titleName = xmlSed.childNodes.item(xmlGet).nodeName;
var titleImg = xmlSed.childNodes.item(xmlGet).text;
if(!titleImg){
titleImg = xmlSed.childNodes.item(xmlGet).textContent;
}
var divMap = document.getElementById(titleName);
if(titleImg!="0" && divMap.style.backgroundImage!="url(img/"+titleImg+")"){
divMap.style.backgroundImage = "url(img/"+titleImg+")";
}else if(titleImg=="0" && divMap.style.backgroundImage != "none"){
divMap.style.backgroundImage = "none";
}else if(titleImg==""){
alert("titleImg is null");
}
}
}
}

XMLHttpRequestObject.send("plid="+plid);
}
setTimeout("getdata()", document.getElementById("refr").value);
}


Спустя 35 минут, 34 секунды (20.10.2010 - 13:04) linker написал(а):
Ну вот условие
if (empty($data_map['img'])) continue;
и говорит, что если пусто img, то перейти к следующей итерации цикла. Вполне возможно что там пустые значения, что у тебя там в базе мне не известно. Еще не понятно, нафига там $count, когда есть поле id. Сессия может и равно нулю, только у тебя условие if($_SESSION["x".$count] != "0") - если не равно нулю.

Спустя 17 минут, 58 секунд (20.10.2010 - 13:22) Jekel написал(а):
в базе куча айдишников..куча строк.....если каждому айдишнику сессию давать это будет не то.

надо ведь нам только 121 запись (в ответе всегда получается поле 11*11). т.е надо создать 121 сессию с id попорядку...и сранивать

база такого типа:
id loc x y
1 0 5 6
и таких записей куча....представь карту по x и y 500*500

Спустя 5 минут, 27 секунд (20.10.2010 - 13:28) Jekel написал(а):
http://cybernews.com.ua/nuke/ вот с моим кодом
http://cybernews.com.ua/nuke2/ вот с твоим кодом
сейчас твой код в таком виде:
	$userdat = mysql_fetch_assoc(mysql_query("SELECT * FROM users WHERE id='1'"));

$count = 0;
$arr_x = array();
$arr_y = array();
for ($y=$userdat["y"]-5; $y<=$userdat["y"]+5; $y++){
$arr_y[] = $y;
}
for ($x=$userdat["x"]-5; $x<=$userdat["x"]+5; $x++){
$arr_x[] = $x;
}
$resource = mysql_query("SELECT * FROM `map` WHERE `loc` = 0 AND `x` IN (" . join(',', $arr_x) . ") AND `y` IN (" . join(',', $arr_y) . ")");

while($data_map = mysql_fetch_assoc($resource)){
if($data_map["img"]){
if($_SESSION["x".$count]!=$data_map["img"]){
$map.="<d".$count.">".$data_map["img"]."</d".$count.">";
$_SESSION["x".$count]=$data_map["img"];
}
}
else{
if($_SESSION["x".$count]!="0"){
$map.="<d".$count.">0</d".$count.">";
$_SESSION["x".$count]="0";
}
}

$count++;
}

Спустя 8 часов, 58 минут (20.10.2010 - 22:26) Jekel написал(а):
эта часть не выполняется...ибо $userdat["y"] и $userdat["х"] равны нулю...
в базе запсей с минус координатами нету...вот оно и 36 строк и выдает тех что есть с x0y0 по x5y5 а тех строк что нету оно не выполняет...while игнорит те строки которых нету и ниже написаный код не выполняется никогда...надо так чтобы если строки не существуют, то $map.="<d".$count.">0</d".$count.">";

if($data_map["img"]){ }else{ 
if($_SESSION["x".$count]!="0"){
$map.="<d".$count.">0</d".$count.">";
$_SESSION["x".$count]="0";
}
}


как такое организовать? blink.gif

Спустя 10 часов, 10 минут, 35 секунд (21.10.2010 - 08:36) linker написал(а):
Jekel
Блин, а чем сложность хранить в базе отрицательные значения?

Зачем плодить темы, в баню хочешь?

Спустя 5 часов, 24 минуты, 10 секунд (21.10.2010 - 14:00) Jekel написал(а):
извини, за мультипост...думал чтоб удобнее было. сорри.
да не надо отрицательные хранить...это и кол. строк увеличит нормально в БД поскольку карт будет много и к каждой хранить отрицаловки....жесть
+ хочется чтоб по уму было сделано) поможете справится?

Спустя 7 часов, 39 минут, 45 секунд (21.10.2010 - 21:40) linker написал(а):
Система координат, где начало ее?

Спустя 2 часа, 28 минут, 51 секунда (22.10.2010 - 00:09) Jekel написал(а):
x0y0

Спустя 6 часов, 14 минут, 42 секунды (22.10.2010 - 06:24) Guest написал(а):
принципиальное решение заключается в разделении операций добычи данных и их обработки.

Но правильным решением будет изменение алгоритма. Нафига обрабатывать кучу отрицательных координат если они все равно не существуют ?

Спустя 1 час, 51 минута, 41 секунда (22.10.2010 - 08:15) linker написал(а):
Действительно, я не въехал тогда причем здесь отрицательные координаты?

Смотри, допустим есть карта размером 10 на 10. Допустим есть координаты:
x=1, y=2
x=3, y=10
Разве данные значения не входят в диапазон выбираемых данных:
`x` IN (0, 1, 2, 3, ..., 10) AND `y` IN (0, 1, 2, 3, ..., 10)
?
Входит и замечательно входит, поэтому выберется 121 запись, мой пример тому подтверждение. Вся проблема, это понять что есть в сессиях, а чего нет, чтобы отобразить нужные значения в браузере. Я так понимаю?
Пока остановимся на это этапе, дальнейшее будет зависеть от твоих разъяснений в подробностях.
$arr_x = array();
$arr_y = array();
for ($y = $userdat["y"] - 5; $y <= $userdat["y"] + 5; $y ++)
$arr_y[] = $y;
for ($x = $userdat["x"] - 5; $x <= $userdat["x"] + 5; $x ++)
$arr_x[] = $x;
$resource = mysql_query("SELECT * FROM `map` WHERE `loc` = 0 AND `x` IN (" . join(',', $arr_x) . ") AND `y` IN (" . join(',', $arr_y) . ")");
while($data_map = mysql_fetch_assoc($resource))
{
...
}

Спустя 14 часов, 27 минут, 50 секунд (22.10.2010 - 22:43) SlavaFr написал(а):
достаточно всего один запрос чтоб получить нужные кординаты.

//не тестировал, возможны ошибки.
SELECT map.img FROM users left join map on map.loc=users.loc WHERE id=$_POST['plid']}
and (map.x>=(users.x-5) and map.x<=(users.x+5) and map.y>=(users.y-5) and map.y<=(users.y+5))


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

Спустя 7 дней, 20 часов, 6 минут, 30 секунд (30.10.2010 - 18:50) Jekel написал(а):
привет, не могу понять, чего не верно выводит результат....должно так выводить:
<t>
<d0>
water.gif
</d0>
<d1>
les.gif
</d1>
<d2>
trava.gif
</d2>
<d3>
trava.gif
</d3>
<d4>
les.gif
</d4>
<d5>
trava.gif
</d5>
</t>
а выводит все одинаковое:
<t>
<d0>
trava.gif
</d0>
<d1>
trava.gif
</d1>
<d2>
trava.gif
</d2>
<d3>
trava.gif
</d3>
<d4>
trava.gif
</d4>
<d5>
trava.gif
</d5>
</t>
в while результат норм выводит но после обработки в foreach дает баг...в чем ошибка кода?
$ud = mysql_fetch_assoc(mysql_query("SELECT * FROM `lol`.`users` WHERE id='1'"));
$cnt = 0;
$ax = array();
$ay = array();
$sd = array();
$ad = array();

for ($y=$ud["y"]-5; $y<=$ud["y"]+5; $y++){
$ay[] = $y;

for ($x=$ud["x"]-5; $x<=$ud["x"]+5; $x++){
$ax[] = $x;
$ad[] = $x.$y;
}}

$rcr = mysql_query("SELECT * FROM `map`.`".$ud["loc"]."` WHERE `y` IN (" . join(',', $ay) . ") AND `x` IN (" . join(',', $ax) . ")");

while($dm = mysql_fetch_assoc($rcr)){
$sd[$dm["x"].$dm["y"]] = $dm["img"];
}


foreach ($ad as $id){
if (isset($sd[$id])){
$map.="<d".$cnt.">".$sd[$id]."</d".$cnt.">";
}else{
$map.="<d".$cnt.">0</d".$cnt.">";
}
$cnt++;
}


Спустя 4 часа, 21 минута, 33 секунды (30.10.2010 - 23:11) SlavaFr написал(а):
Цитата (Jekel @ 30.10.2010 - 15:50)
в while результат норм выводит но после обработки в foreach дает баг...в чем оши бка кода?

делай echo в местах, где ты подозреваеш баг. Еще лучше инсталируй дебагер, наприм ер xdebug.

Спустя 26 минут, 49 секунд (30.10.2010 - 23:38) Jekel написал(а):
да дебагеры ничего не находят, все написано правильно...логика не правильная поход у...у кого какие предложения? huh.gif

Спустя 17 минут, 34 секунды (30.10.2010 - 23:56) SlavaFr написал(а):
Цитата (Jekel @ 30.10.2010 - 20:38)
все написано правильно...логика не правильная

странно както, все правильно кроме логики.
а пытался так зделать, как я тебе подсказал?
а зачем сесзон насилуеш?
а почему не хочеш javasript переделать, чтоб просто правильно реагировать на недос тающие елементы <d> в xml ?

Спустя 22 минуты, 55 секунд (31.10.2010 - 00:19) Jekel написал(а):
да так решил делать...да и меня теперь капец как интересует что это за полтергейст!
     while($dm = mysql_fetch_assoc($rcr)){
$sd["c".$dm["x"].$dm["y"]] = "x".$dm["x"]."y".$dm["y"]." - ".$dm["img"];
}
foreach ($ad as $id){
if (isset($sd[$id])){
$map.="<d".$cnt.">".$sd[$id]."</d".$cnt.">";
}else{
$map.="<d".$cnt.">0</d".$cnt.">";
}
$cnt++;
}

выводит:
<d0>
x4y6 - trava.gif
</d0>
<d1>
x5y6 - trava.gif
</d1>
<d2>
x6y6 - trava.gif
</d2>
<d3>
x7y6 - trava.gif
</d3>
<d4>
x8y6 - trava.gif
</d4>
<d5>
x9y6 - trava.gif
</d5>
хотя оно в БД не так))))))))под x4y6 - water.gif
а если так:
 while($dm = mysql_fetch_assoc($rcr)){
$sd["c".$dm["x"].$dm["y"]] = "x".$dm["x"]."y".$dm["y"]." - ".$dm["img"];
if($dm["x"]==4 && $dm["y"]==6){
echo "x".$dm["x"]."y".$dm["y"]." - ".$dm["img"];
}
}

выводит:
x4y6 - water.gif
полтергейст) что делать?

Спустя 16 часов, 12 минут, 27 секунд (31.10.2010 - 17:31) Guest написал(а):
офигительный пример как не надо просить о помощи. куски кода, куски вывода, жалобы на баг, но никакой инфы что за баг...

невольно вспоминается анекдот "Угадайте чей папа пришел" (с)
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.