Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Оптимизация работы скрипта с MySQL, на примере проекта http://chatman.ru 
:(
    Опции темы
OverClocker
Дата 22.4.2006, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 12.11.2005

Репутация: нет
Всего: нет



Уважаемые дамы и господа, не сочтите за рекламу, но нужна помощь с оптимизацией скриптов форума собственного написания. Итак, у нас с товарищем есть форум, который мы сами написали - http://chatman.ru. Очень долго генерируются странички. Вот например, я недавно добавил http://chatman.ru/1 тут (ссылка с единичкой на конце) новую вещь. А именно: юзеры, отпостовавшие последними мессагу и дату мессаги. Страничка стала ещё больше грузиться. Заходим просто на chatman.ru:
Цитата

Время генерации скрипта: 0.338 сек.

Далее идём на модифицированную вещь http://chatman.ru/1 :
Цитата

Время генерации скрипта: 19.954 сек.

Теперь идём смотреть категорию, скажем новости http://chatman.ru/1/index.php?show=messages&id=6 :
Цитата

Время генерации скрипта: 9.819 сек.

И далее идём смотреть какую-нибудь тему: http://chatman.ru/index.php?show=message&a...941&page=76 :
Цитата

Время генерации скрипта: 0.999 сек.

Ну одна секунда это, конечно, не так много, как было в других случаях, но всё-таки много.

Я так понял, что время генерации скрипта зависит от того, сколько и каких запросов идёт к базе MySQL.
Вот, например, раньше http://chatman.ru/index.php грузился ещё медленнее. Но теперь всё ответы на темы я начал записывать в базу и считывать их оттуда, а на главное странице, где категории, там мы складываем все значение из тем, что, конечно, тоже не совсем правильно (я так понимаю, что в категориях тоже надо писать количество созданных тем и ответов)

Скажите, можно ли как-нибудь оптимизировать работу скриптов, не записывая количество чего-либо в базу, а всё также (как сейчас) посчитывая mysql_numrows();? Расскажите поподробнее, пожалуйста. 
PM MAIL WWW   Вверх
Mal Hack
Дата 22.4.2006, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 8
Всего: 261



Все можно, но подходить надо лифференцировано. Дело даже зачастую не в количестве запросов, а в не грамотной обработке. 
PM ICQ   Вверх
OverClocker
Дата 22.4.2006, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 12.11.2005

Репутация: нет
Всего: нет



Mal Hack,  ну, вот например, как я уже говорил на http://chatman.ru/1 я создал фичу, где отображается, кто последний ответил на тему. Вот кусок кода, который это обрабатывает:

Код

    $sql_last="SELECT * FROM ".$db_prefix."messages WHERE sid='".$rs['id']."' AND asort<>'9999999999' ORDER by asort DESC"; // делаем выборку из мессаг, где поле "sid" (ID категории, к которой принадлежит эта тема) равен текущей обрабатываемой категории
    $query_last=mysql_query($sql_last);
    $rs_last=mysql_fetch_array($query_last);
    $rs_last['subject']=Replace_Critical($rs_last['subject']); // моя собственная функция, в которой содержаться разные str_replace'ы критических символов, таких, как <, > и т.д.
    $subject_small=$rs_last['subject']; // здесь будет содержаться то, что будет выведено конкретно на экран. (название темы, в которой недавно постанули)
    $rs_last['subject']=str_replace("\"", "", $rs_last['subject']); // заменяем кавычки в этой вещи, чтобы не было глюков, когда при всплывающем меню обрывы строки были
    if (strlen($subject_small)>30)  // если большое название темы, обрезаем до 28 символов
    {
        $subject_small=substr($subject_small,0,28)."...";
    }

    $sql_last_use="SELECT * FROM ".$db_prefix."messages WHERE parentid='".$rs_last['id']."' ORDER by id DESC"; // ищем последнего, кто отпостовал конкретно в теме, а не создал новую.
    $query_last_use=mysql_query($sql_last_use);
    if (mysql_num_rows($query_last_use)<>0) // если в последней теме есть ответы, ищем, кто там написал ответ последний. И если этот "кто-то" нашёлся, то выполняем:
    {
        $rs_last_use=mysql_fetch_array($query_last_use);
        $rs_last['authorid']=$rs_last_use['authorid']; // тогда последний, кто отпостовал будет тот, кто последний оставил мессагу в теме.
        $rs_last['date']=$rs_last_use['date']; // тоже самое с датой, кто последний отпостовал
    }
    $lastuser=id2login($rs_last['authorid'], &$db_prefix); // шали этого "кто-то", однако мы должны получить его имя, т.к. в базе сохраняется только ID юзера.
    $lastuser=Replace_Critical($lastuser); // опять же моя функция, заменяющая критические символы
    $lastuser_small=$lastuser; // обрезаем логин юзера, если слишком большой
    if (strlen($lastuser)>15)
    {
        $lastuser_small=substr($lastuser_small,0,12)."...";
    }
    $datetime=date("j.n.Y G:i"); // получаем текущую дату
    $datetime=split(" ",$datetime); // разбиваем на дату и время
    $date=$datetime[0];
    $time=$datetime[1];
    $postdate=$rs_last['date']; // дата, которая будет отображаться
    $rs_last['date']=split(" ", $rs_last['date']); 
    if ($rs_last['date'][0]==$date) // если совпадает дата с текущей, то выводим, что мессага отпостована сегодня
        $postdate="Сегодня ".$rs_last['date'][1];
 
PM MAIL WWW   Вверх
Mal Hack
Дата 22.4.2006, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 8
Всего: 261



OverClocker, исскуство отладки и оптимизации целая наука, тут надо рассматривать всю систему в целом и т.п.
Есть,  конечно, такое правило, что первым делом, программа должна иметь оптимальный алгоритм, потом минимальное использование ОП для реализации алгоритма, третье - фичи оптимизации.

Примеров много, где-то они тут уже обсуждались.
  

Это сообщение отредактировал(а) Mal Hack - 22.4.2006, 20:43
PM ICQ   Вверх
comnimh
Дата 25.4.2006, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 25.4.2006

Репутация: нет
Всего: нет



Покажи  Replace_Critical.  Может  ее  заменить  на  пару  стандартных  и  регэкспов?
И  почему  бы  тебе  не  делать  обработку  ткста  мессаги  непосредственно  при  ее  публикации? 

Это сообщение отредактировал(а) comnimh - 25.4.2006, 12:16
PM MAIL   Вверх
ZlojEzh
Дата 26.4.2006, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.10.2005
Где: Киев, Украина

Репутация: 1
Всего: 15



OverClocker, попробуй поставить себе APD или на худой конец PEAR::Benchmark
(APD конечно конечно лучше намного)
на глаз очень трудно прикинуть, какие именно участки кода тянут на себя слишком много ресурсов
а с помощью APD - 10 минут анализа трейса - и все узкие места перед тобой как на ладони

а вот если уже после этого станет ясно, что проблема именно с запросами - тогда начинаем оптимизировать структуру БД

например случай с последним сообщением в теме:
я бы забил на нормализацию БД и хранил эту инфу вместе с информацией о теме
тогда одна строчка с списке тем форума будет формироваться из одного запроса

 
PM MAIL ICQ   Вверх
OverClocker
Дата 26.4.2006, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 12.11.2005

Репутация: нет
Всего: нет



Цитата(comnimh @  25.4.2006,  12:14 Найти цитируемый пост)
Покажи  Replace_Critical.  Может  ее  заменить  на  пару  стандартных  и  регэкспов?

Не вопрос!

Код

function Replace_Critical($str)
{
    $str=stripslashes($str);
    $str = str_replace("<", "&lt;", $str);
    $str = str_replace(">", "&gt;", $str);
    $str = str_replace("\n", "<BR>", $str);
    $str = str_replace("\r", "", $str);
return $str;    
}



Цитата(comnimh @  25.4.2006,  12:14 Найти цитируемый пост)
И  почему  бы  тебе  не  делать  обработку  ткста  мессаги  непосредственно  при  ее  публикации? 

Можно! Там ещё и смайлики реплейсятся. Ну это другая история...
Мне кажется, что скорей всего всё из-за того, что много запросов к базе идёт...



Цитата(ZlojEzh @  26.4.2006,  09:44 Найти цитируемый пост)
OverClocker, попробуй поставить себе APD или на худой конец PEAR::Benchmark
(APD конечно конечно лучше намного)
на глаз очень трудно прикинуть, какие именно участки кода тянут на себя слишком много ресурсов
а с помощью APD - 10 минут анализа трейса - и все узкие места перед тобой как на ладони

Классно, классно! Я хочу это посмотреть! А где?


Цитата(ZlojEzh @  26.4.2006,  09:44 Найти цитируемый пост)
например случай с последним сообщением в теме:
я бы забил на нормализацию БД и хранил эту инфу вместе с информацией о теме
тогда одна строчка с списке тем форума будет формироваться из одного запроса

Да, если хранить всё в базе, будет попроще. Хочу сделать, но лень. Но если это действительно оптимизирует работу - сделаю. 
PM MAIL WWW   Вверх
ZlojEzh
Дата 26.4.2006, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.10.2005
Где: Киев, Украина

Репутация: 1
Всего: 15



PM MAIL ICQ   Вверх
OverClocker
Дата 26.4.2006, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 12.11.2005

Репутация: нет
Всего: нет



ZlojEzh, Благодарствую  smile 

Да, ребят, спасибо всем за ответы! smile 

P.S.: ZlojEzh, мне стыдно это спрашивать... Но всё-таки, как ставить APD на шелле? И как запускать потом...  smile  

Это сообщение отредактировал(а) OverClocker - 26.4.2006, 18:11
PM MAIL WWW   Вверх
madFobos
Дата 27.4.2006, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.12.2005

Репутация: нет
Всего: 3



У тебя в базе индексы используются? Потому что без СУБД очень сильно грузит систему. 
PM MAIL   Вверх
ZlojEzh
Дата 27.4.2006, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.10.2005
Где: Киев, Украина

Репутация: 1
Всего: 15



OverClocker, на шелле не получится
надо, как минимум, доступ к php.ini и к папке, где хранятся .so'шки

в таком случае вариант - PEAR::Benchmark
им, конечно, не так удобно пользоваться - приходится вручную задавать все точки для замера времени
но хоть что-то...

по-поводу твоего скрипта:
строка 13:
Код
$sql_last_use="SELECT * FROM ".$db_prefix."messages WHERE parentid='".$rs_last['id']."' ORDER by id DESC";

имхо, select * здесь не надо - ты используешь только два поля
выбирать все записи из темы тоже не надо - делаем limit 1
строка 2 - аналогично:
Код
$sql_last="SELECT * FROM ".$db_prefix."messages WHERE sid='".$rs['id']."' AND asort<>'9999999999' ORDER by asort DESC";

нужна ведь только одна запись (насколько я понял) - делаем limit 1

вообщем смысл таков - из БД выбираем только те данные, которые используем

и еще - в mysql_fetch_array ставь второй параметр MYSQL_ASSOC
повышение производительности это вряд ли даст )), но если понадобится на экран выводить (или еще чего) - удобней будет

если есть возможность - в mysql включаем лог медленных запросов
через день анализируем и проверяем соответствующие скрипты на предмет возможной оптимизации (или же, как уже сказал madFobos, создаем соответствующие индексы в таблицах (здесь главное не переусердствовать) )

Replace_Critical, имхо, стоит использовать при записи данных в БД, а не при выводе
(аналогично: проверка длины логина)

split заменяем на explode - в твоем случае реги не нужны (на форуме об этом уже писалось не один раз)


вообщем пройдись по всем скриптам обращая внимание на такие моменты
имхо, получишь неслабое ускорение работы сайта

Добавлено @ 10:04 
да, кстати - если получится проинсталить apd:
читаем здесь
http://apd.communityconnect.com/faq.html
http://ua2.php.net/manual/en/ref.apd.php

и стоит посмотреть вывод phpinfo()
может apd уже включен
 
PM MAIL ICQ   Вверх
OverClocker
Дата 28.4.2006, 08:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 12.11.2005

Репутация: нет
Всего: нет



ZlojEzh, спасибо тебе! Очень содержательно! Буду пробовать! Очень рад, что настолько подробно, не поленился, и ответил! Спасибо!

Кстати, а где скачать PEAR::Benchmark и как его установить?..  smile  

Цитата(madFobos)

У тебя в базе индексы используются? Потому что без СУБД очень сильно грузит систему.  

Хм... Индексы? А как создать их через PhpMyadmin? И что они из себя вообще представляют? 

Это сообщение отредактировал(а) OverClocker - 28.4.2006, 08:09
PM MAIL WWW   Вверх
madFobos
Дата 1.5.2006, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.12.2005

Репутация: нет
Всего: 3



Цитата(OverClocker @  28.4.2006,  08:06 Найти цитируемый пост)
Кстати, а где скачать PEAR::Benchmark и как его установить?


Это должно быть на pear.php.net

Цитата(OverClocker @  28.4.2006,  08:06 Найти цитируемый пост)
Хм... Индексы? А как создать их через PhpMyadmin? И что они из себя вообще представляют? 


В phpMyAdmin точно не знаю, т.к. редко им пользуюсь, но по идее там в структуре таблицы это все должно быть. Индексы представляют собой указатели на нужную тебе информацию. Скажем твоя таблица содержит 1.000 записей и если в ней искать строку по id = 5, то базе необходимо будет полностью считать весь файл таблицы и путем "пробега" по нему найти твое id = 5. При наличии же индекса на колонку создается нечто вроде отдельного файла (хотя в каждой базе своя реализация), где хранятся только значения непосредственно твоего id и адреса строк (указатели) в основной таблице. Т.к. файл индекса меньше по объему и представляет собой обычно бинарное дерево, то поиск ведется очень быстро, процессор грузится на несколько порядков меньше, соответственно и время обработки значительно быстрее. Это вкратце  smile 
 
PM MAIL   Вверх
IZ@TOP
Дата 3.5.2006, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 1
Всего: 73



OverClocker, как совет по оптимизации РНР кода, могу посоветовать для начала заменить все split на explode, а множественные str_replace объеденить в один:

Код

$text = str_replace(array('value1', 'value2', 'valueN'), array('value1', 'value2', 'valueN'), $text);


А вообще, лучше всего сходить на курсы по РНР, только на хорошие, а то иногда попадаются места где незнают что такое file_get_contents и прочее... еще есть много хороших книжек (советую купить хотя бы одну, подробнее ищи на форуме).  


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
stmamont
Дата 4.5.2006, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 343
Регистрация: 13.3.2004
Где: влг

Репутация: нет
Всего: 3



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


--------------------
user posted image
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса

Внимание: данный раздел предназначен для решения сложных, нестандартных задач.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Для профи | Следующая тема »


 




[ Время генерации скрипта: 0.1380 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.