[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Веб студии, не все одинаково полезны
Страницы: 1, 2, 3
T1grOK
Так случилось, что попался проект от одной известной веб-студии, который требовал оптимизации. Сайт с трудом дышал при 1-2 пользователей при неплохом VPS.
Начал смотреть, по коду и БД можно было судить, что над проектом работало уже много программистов от грамотных и до безобразия бездарных. Обо всем по порядку.
1) БД. Туча индексов, композитные индексы по 15 строк, которые в принципе не могут быть задействованы, а те которые задействовались в большинстве случаев имели низкую селективность.
В итоге таблица в 500 000 строк просматривалась полностью.

Подумаешь! Индексы для слабаков. Мы за хардкор. :D

2) Профилирование показало, что на главной странице выполняется 400 запросов. Детальный анализ показал, что 323 из них идентичны! На остальных страницах также наблюдалать подобная ситуация.

Подумаешь! Мы не бедняки, чтоб на запросах экономить.

3) Контрольный в голову был после обнаружения подобных участков кода повсеместно.
ORM::factory('product')->where("watch", "=", 1)
->
and_where("dateend",">",time())
->
find_all()
->
count()

Это участок кода на Kohana фреймворк с использованием ORM. Для тех кто не знает, данная запись выберет все записи из БД подходящие под критерии и заполнит этими данными модели, а потом просто подсчитает их количество.
На текущий момент такой запрос выбирает каких то 420 000 строк извлекая из БД 110мб данных. Чтоб такой запрос отработал, на моем пк с SSD уходит 17 секунд.
Благо результат кешируется на 3 часа, а то бы для проекта пришлось арендовать датацентр :D
Но как писал выше, такие ситуации повсеместны, есть менее критичные места, но которые и не кешируются, а просто таскают данные создавая бесполезную нагрузку.

COUNT(*) не не слышали.

Вот такой вот неприятный и уже не первый подобный опыт.

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
glock18
Цитата (T1grOK @ 25.12.2013 - 17:56)
Так случилось, что попался проект от одной известной веб-студии, который требовал оптимизации

Уже сама такая формулировка никогда не сулит ничего хорошего ))
glock18
Цитата (T1grOK @ 25.12.2013 - 17:56)
3) Контрольный в голову был после обнаружения подобных участков кода повсеместно.

ORM::factory('product')->where("watch", "=", 1)
            ->
and_where("dateend",">",time())
            ->
find_all()
            ->
count()



Похожий я видел у своего сокурсника, когда диплом писали. Дело было на yii версии 1.0.3, кажется. Уже точно не помню, но он там выбирал все записи, после чего стандартным for'ом выбирал нужные 10 из 100500 по оффсету (причем даже не for ($i = $offset;...;$i++), а по всей выборке с проверкой оффсета внутри тела цикла). После чего скармливал критерии пейджеру (там кажется как-то так было с activeRecord, "айайай" с тех пор не использовал больше), и тот делал все сам, превращая всю прежнюю работу в бессмыслицу :D Как-то все так, я помню, что мой смех было очень долго не остановить.

После этого случая я недолюбливаю ORM. Дай его в руки неумехи, и получишь вот такого монстра. Ошибки даже считать смысла нет - все в целом одна огромная ошибка.
sergeiss
T1grOK, читал как триллер. Ближе к концу ожидал описание того, как ты выслеживаешь "аффтора" и в жёсткой форме объясняешь ему, что он не прав smile.gif

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
bestxp
Просто не умеют готовить инструментарий что выбрали, видимо поэтому там запросы в цикле или еще чего xD

Орм хорошо, но мне нравиться больше DataMapper подход))) но это друга история
T1grOK
Цитата (sergeiss @ 25.12.2013 - 19:00)
T1grOK, читал как триллер.

Триллер продолжается :)
Цитата (T1grOK @ 25.12.2013 - 17:56)
2) Профилирование показало, что на главной странице выполняется 400 запросов. Детальный анализ показал, что 323 из них идентичны!

Вскрытие показало, что все модели наделены конструктором, с таким содержанием:
    function __construct() {
parent::__construct();
$this->language = ORM::factory('language')->where('name', '=', Request::instance()->param('lang'))->find()->id;
}

То есть, для каждой строки извлеченной из БД, по ORM фэншую, будет создан экземпляр модели и соответственно для каждой будет создана модель language за которой последует запрос к БД.
Да запрос простой.
Да запрос выполняется за счет индексов очень быстро.
Да в большинстве случаев СУБД достанет результат из кеша.

НО! Запросы все же дергают драйвер и саму СУБД, а также множество моделей language сидят в памяти.

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
T1grOK
Цитата (glock18 @ 25.12.2013 - 18:43)
Похожий я видел у своего сокурсника, когда диплом писали. Дело было на yii версии 1.0.3, кажется. Уже точно не помню, но он там выбирал все записи, после чего стандартным for'ом выбирал нужные 10 из 100500 по оффсету (причем даже не for ($i = $offset;...;$i++), а по всей выборке с проверкой оффсета внутри тела цикла).

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

echo 'Hello Word!';

уже повод переходить на фреймворки.

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
T1grOK
Цитата (T1grOK @ 25.12.2013 - 17:56)
3) Контрольный в голову был после обнаружения подобных участков кода повсеместно.
ORM::factory('product')->where("watch", "=", 1)
            ->and_where("dateend",">",time())
            ->find_all()
            ->count()


Цитата (glock18 @ 25.12.2013 - 18:31)
На текущий момент такой запрос выбирает каких то 420 000 строк

А теперь попробуйте угадать сколько будет выполнено запросов ввиду
function __construct() {
parent::__construct();
$this->language = ORM::factory('language')->where('name', '=', Request::instance()->param('lang'))->find()->id;
}

Да, 420 000!

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
glock18
Цитата (T1grOK @ 27.12.2013 - 06:47)
Цитата (glock18 @ 25.12.2013 - 18:43)
Похожий я видел у своего сокурсника, когда диплом писали. Дело было на yii версии 1.0.3, кажется. Уже точно не помню, но он там выбирал все записи, после чего стандартным for'ом выбирал нужные 10 из 100500 по оффсету (причем даже не for ($i = $offset;...;$i++), а по всей выборке с проверкой оффсета внутри тела цикла).

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

echo 'Hello Word!';

уже повод переходить на фреймворки.

Ну, так как там диплом был, все таки его, как и меня, никто не спрашивал на чем он хочет писать. Другое дело, что... Я вообще то ярый защитник важности образования, а тут дипломная работа с такими ляпами (у него такое было повсеместно).

А насчет спорных ситуаций тут очень интересный момент. В математике все решения задач сводятся к приведению задачи к ранее решенной/решенным. Самостоятельное обучение у многих в программировании обычно строится таким же образом: не зная как возвести в степень, такой программист вместо $a = pow(4, 100); забабахает цикл. Задача решена, а ему даже невдомек, что решение мягко говоря субоптимальное. Так продолжается всю жизнь, и ничего не меняется обычно. В сайтостроении такая проблема очень хорошо видна в понимании sql, например, можно очень легко заметить это по вопросам и их формулировкам на этом форуме.
glock18
Цитата (T1grOK @ 27.12.2013 - 06:54)
Цитата (T1grOK @ 25.12.2013 - 17:56)
3) Контрольный в голову был после обнаружения подобных участков кода повсеместно.
ORM::factory('product')->where("watch", "=", 1)
            ->and_where("dateend",">",time())
            ->find_all()
            ->count()


Цитата (glock18 @ 25.12.2013 - 18:31)
На текущий момент такой запрос выбирает каких то 420 000 строк

А теперь попробуйте угадать сколько будет выполнено запросов ввиду
function __construct() {
parent::__construct();
$this->language = ORM::factory('language')->where('name', '=', Request::instance()->param('lang'))->find()->id;
}

Да, 420 000!

А говорили, что "всего" около 400 за http-запрос wink.gif Возможно, что запрос этот кешируется где-то на уровне ORM, и так же, возможно, что даже объект отслеживается, и в результате везде возвращается ссылка на один и тот же объект. В этом случае ORM даже сыграла на пользу производительности в какой-то мере biggrin.gif
phz
Попадались такие сайты у меня на работе. Последний был на битриксе. Это был тихий ужас.. Через этот сайт прошло вроде 5 разработчиков.. и в итоге полный гомнокод.. На одной странице подключено было куча одинаковых скриптов.. запросов... Клиенту всё нравилось, сайт работал... не считаю падений из-за нагрузки. Чтобы переделать, оптимизировать - клиент не хотел и говорить на эту тему. В итоге мы отказались и сайт качует к следующим разработчикам sad.gif

Чтобы что-то добавить из плюшек заказчика, приходилось так же писать или изгибаться под то что написано. Когда говорю менеджеру что сделаю сейчас так же как и всё там сделано - получал - лишь бы работало визуально ohmy.gif и клиент был доволен
T1grOK
Цитата (glock18 @ 27.12.2013 - 07:01)
Возможно, что запрос этот кешируется где-то на уровне ORM, и так же, возможно, что даже объект отслеживается, и в результате везде возвращается ссылка на один и тот же объект.

"Фатальные" страницы у меня не выполняются даже при выделении 128мб под php скрипт. И судя по тому, что обработку Language я вынес в отдельный синглтон класс у меня количество запросов сократилось с 400 до 77, можно судить, что если у меня было бы1000 записей, то и столько же запросов.
Так, что с каким то хитрым кэшированием вариант не канает.

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
T1grOK
Цитата (phz @ 27.12.2013 - 08:59)
Через этот сайт прошло вроде 5 разработчиков.. и в итоге полный гомнокод..

Регулярно сталкиваюсь с такими проектами. Большой проект, год разработки, каждые 2 месяца приходит свободный программист которого нужно временно занять или уходят совсем с проекта и тогда еще подыскивают новые лица.
Иногда даже были случаи, что привлекали новых программистов на пару недель.
Сейчас нахожу коммиты в SVN от 7 программистов, хотя регулярно на проекте находится всего лишь 2.
А ведь, чтобы знать все тонкости проекта(крупного) необходимо потратить месяц(вот только не надо писать тем, кто магазины за 3 дня пишут rolleyes.gif ).
В результате имеем посредственное качество кода.

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
T1grOK
Многие веб студии нынче практикуют привлечение фрилансеров для разовых работ. Зачем платить грамотному штатному работнику 1500-2000 баксов в месяц(уровень Киева), если можно, хоть и с гемором, найти какого-то Васю из Урюпинска, который сделает работу за 700, а может и того дешевле.

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
inpost
T1grOK
Ну так и заказы не такие большие. Не каждый же сможет заплатить X*1000$ за хороший код и хороший сайт.
Мелким и средним сайтам не нужен нормальный код абсолютно, зачем время своё и чужое тратить, достаточно быстро и дешево написать и пусть пользуются на здоровье.
В связи с этим и программисты есть слабого уровня, как раз для мелких и малоденежных проектов.

_____________
Обучаю веб-программированию качественно и не дорого: http://school-php.com
Фрилансер, принимаю заказы: PHP, JS, AS (видео-чаты). Писать в ЛС (Личные сообщения на phpforum).
Быстрый ответ:

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