Javascript-форум (https://javascript.ru/forum/)
-   Серверные языки и технологии (https://javascript.ru/forum/server/)
-   -   Слишком большое время обработки php+sql (https://javascript.ru/forum/server/12477-slishkom-bolshoe-vremya-obrabotki-php-sql.html)

Jekel 19.10.2010 15:37

Слишком большое время обработки php+sql
 
Здравствуйте, написал кодец, но время обработки у него 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;
	}
}

Gvozd 19.10.2010 15:45

индексы по полям x,y,loc расставил?

Jekel 19.10.2010 15:52

не имею понятия как это и что это, вот сейчас чту сижу...спасибо за наводку)

Kolyaj 19.10.2010 16:13

Ещё про join заодно почитай.

B@rmaley.e><e 19.10.2010 19:22

Возможно есть смысл сделать выборку из map одним запросом.

subzey 19.10.2010 20:23

[sql]SELECT * FROM users RIGHT JOIN map ON map.y BEETWEEN users.y-5 AND users.y+5 AND map.x BEETWEEN users.x-5 AND users.x+5 WHERE id={$id} ORDER BY map.x, map.y[/sql] Что-то вроде этого, проверить не смогу.

Jekel 19.10.2010 22:55

:blink: хм, спасибо..ща буду чет колупать

Jekel 20.10.2010 01:13

проиндексировал....было так:
Код:

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;[/CSS]

стало так:
Код:

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;

может есть лучше варианты?

Gvozd 20.10.2010 02:44

с учетом поправок B@rmaley.e><e, и subzey, данная таблица должна показывать хорошее время запроса.
если нет, то почему вы не написали, результаты нового тестирования?
PS ваша база микроскопическая вообще-то.
я бы посоветовал проверять на большой базе

Jekel 20.10.2010 03:27

проверил на большой базе
в таблице 500.000 строк время обработки около 500ms ;)
надо меньше 100ms ибо запросы на серв каждых 100мс поступают

Jekel 20.10.2010 03:54

С помощью неких личностей написал такое...но работает не коректно, выдает не полный ответ...читает мало с базы( должно читать 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++; 
    }

Gvozd 20.10.2010 09:12

Цитата:

Сообщение от Jekel
if (empty($data_map['img'])) continue;

оно, нэ?

Kolyaj 20.10.2010 09:40

Цитата:

Сообщение от Jekel
надо меньше 100ms ибо запросы на серв каждых 100мс поступают

А сетевые задержки вы не учитываете?

Gvozd 20.10.2010 09:55

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

subzey 20.10.2010 12:20

Часто ли от клиента дожна идти какая-то информация? Часто ли будут меняться переданные данные?

Если данные меняются относительно редко (раз в несколько секунд), можно использовать COMET, чтобы не гнать клиенту одинаковые данные.

Если достаточно часто, то можно устроить некое подобие event-source (IE с файрфоксом, насколько я знаю, event-source не умеют). А именно — в старых добрых традициях чата Бородина слать последовательно теги <script> в скрытый ифрейм. Тогда можно сэкономить время на SYN→ACK→SYN-ACK и передаче заголовков запроса и ответа.

Другие предложения? Самому интересно. :)


Часовой пояс GMT +3, время: 10:41.