Как стать автором
Обновить

Комментарии 58

>Или вы выбираете из БД много строк, но используете только некоторые из них?

>Можно ли какие-то из этих запросов превратить в один запрос или вообще убрать?

Иной раз как раз использование десятков мелких запросов даст больший прирост производительности, чем один «трехэтажный», или «ручное» исключение записей из результата вместо «скульного». В обоих случаях как раз за счёт кэширования на уровне БД/ORM/модели. Такие ситуации часто встречаются, когда пользователям показываются почти одни и те же данные (например, детальный список пользователей онлайн, кроме самого пользователя)
Смотрите мой коммент ниже насчёт IN().
По факту это должен быть очень кривой запрос, что бы такое случилось с большим кол-вом JOIN'ов и весьма объёмными таблицами.
Именно так. Т.е. в теории да, вполне реально чтобы один запрос исполнялся дольше кучи мелких, но на практике это бывает редко. Не будем забывать про накладные расходы на собственно исполнение запроса.
Вообще часто к излишим запросам приводит ORM, так как часто без дополнительных указаний они не генерируют запросы с JOIN и как правило не умеют использовать IN возможность MySQL'a (а она как раз можно сказать панацея от слишком сложных запросов с кучей JOIN — бъём на 2 запроса и вдруг всё работает сильно быстрее! ).
Да, N+1 Query очень «популярная» ошибка начинающих (в ORM) программистов.
В Rails кстати есть удобное средство которое само в реальном времени советуюе дописывать и убирать «eager loading» — Bullet. Предупреждения выбрасывает в Growl, в лог или джаббер. Всем советую, под виндой с Growl for Windows работает. Тормозит тоже хорошо, но в development не страшно=)
а что за средство, можете подсказать?
Если индексы расставлены правильно трехэтажный JOIN может работать быстрее нескольких IN (но если начнут лочится таблицы участвующие в JOIN — можно вешаться). IN ООООООЧЕНЬ помогает если используется большой LIMIT.
Какое-то странное сравнение join и in… Как их можно сравнивать?
Хмъ, видимо, кто-то таки считает, что их можно сравнивать :) А меж тем они друг с другу не мешают, как теплое — мягкому )
В веб разработке в большинстве случаев используются запросы с обычными LEFT JOIN, которые можно разбить на несколько запросов с использованием IN.
Ну из моей практики, в сайтах где есть пользователи почти во всех запросах идут JOIN на таблицу юзеров. И так сквозь весь сайт — тут-то и начинаются тормоза из-за того — я выношу запрос в отдельный SELECT с IN — очень эффективно.
Истерия вокруг NoSQL действительно очень спорная.
Понравился диалог про увеличение производительности в 26 раз простым индексом.
Кто бы статейку про грамотное использование индексов накидал. А так из моей практики чаще всего проблема в большом количестве запросов на страницу.
А что конкретно интересует? составьте примерный список интересующих вопросов — могу по нему написать статью, а то уж больно обширный вопрос с одной стороны, а с другой весьма неплохо расписанный в общих чертах в документациях
Можно начать с начала — что такое индексы в БД, что они дают, какие столбцы выбирать под индексы. :)
Можно, имхо, начать с индексов для различных типов связей таблиц — впрочем это база и, думаю, более-менее ясно всем. Гораздо более сложны, опять же имхо, составные индексы (по нескольким полям), особенно когда поля разных типов. Вот про них и было бы интересно почитать — как определить необходимость, как правильно составить, как удостовериться в результате или т.п.
НЛО прилетело и опубликовало эту надпись здесь
— пока индекс в память умещается — все замечательно, как перестанет — производительность резко падает
что логично и очевидно, с диска читать медленнее, чем из памяти. Но производительность не упадет ниже чем если бы индекса вообще не было. Благо память сейчас дешевая, а раз индекс достаточно велик, чтобы не влезать в память, то имеет смысл думать о своем сервере, с хорошим объемом памяти.

— хотя об этом часто пишут, не смог добится сильного отличия в скорости между полями CHAR и VARCHAR
различие имеет место только если у вас все столбцы фикисированных типов данных, т.к. mysql гораздо легче определить смещение искомых данных. Если у вас столбец строго 15 символов, то лучше использовать CHAR, т.к. будет затрачено меньше места (на один байт для каждой строки) ла и это просто сематично, по типу данных сразу можно составить представление о самих данных. В случае CHAR, точнее фиксированных таблиц, легче восстановить таблицу в случае сбоя.

— при росте индекса скорость вставки уменьшается нелинейно и может стать критично низкой
это тоже в принципе очевидно и логично, для избежания этого есть partitions, где вставка идет только в последнюю партицию.

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

— разбиение таблиц вешь замечательная, но сильно замедляет вставку
вы про какое разбиение?

force index вообще крайне редко стоит использовать, все таки это средство обмануть оптимизатор, а поскольку он работает вполне хорошо, то сто раз стоит подумать, кто не прав, составитель запроса/индексов или оптимизатор. Но он ошибается все же иногда, так что штука полезная ;)

В любом случае, конечно, вопросы индексов напрямую зависят от данных, и делать их надо не по шаблону, а вдумчиво и вручную. Но общие правила и подходы все таки есть.
Вы знаете, эмпирический метод познания хорош когда подкреплен теорией. Общих рекомендаций и чисто эмпирических заточек в сети полно, а вот нормального анализа я еще не встречал.
я с вами не согласен.
я лично видел ситуацию, когда использование force index помогало, потому что мускул не хватал мой индекс и вообще делал full scan. время запроса уменьшалось с нескольких секунд до меньше одной секунды и они переставали попадать в slow-log.
забыл сказать, что в таблице не мало записей — 550 тысяч строк
НЛО прилетело и опубликовало эту надпись здесь
Готов помочь по oracle, в нем существенно больше нюансов. Ну или напишу отдельную по нему.
Был ли у вас опыт работы с MS SQL Datavaser Engine Tuning Advisor? Насколько можно доверять его советам по расстановке индексов?
Была у меня мысль — 80% всех проблем с индексами можно решить путем очень простых действий. Но ведь если такую статью написать — закритикуют — «банальные вещи, не интересно». :-) Вот думаю стоит ли.
думаю, стОит разбить на уровни — для новичков/для профи. типа, если считаешь себя профи — читай п.8 :)
а для новичков — подробней, но без разжевывания. лучше привести ссылку на отдельную статью с разжеванными базовыми вещами в личном блоге или у коллег по цеху.
Нет «если считаешь себя профи см п. 8 не сработает». Я когда студентам как-то читал курс по юниксу они просили — мы профи — давайте сразу про пересборку ядра. При этом не знали базовых вещей.

Как результат наиболее простые и важные вещи прочитают только профи ;-)
НЛО прилетело и опубликовало эту надпись здесь
Вопрос, частично касающийся данной темы, но может кто знает. Как использовать FORCE INDEX в Zend Framework?
НЛО прилетело и опубликовало эту надпись здесь
Да. Сталкивался с ситуациями, когда именно MySQL не хотел использовать индексы, только FORCE INDEX уменьшал время выполнения запроса с нескольких секунд до нескольких мс.
via SpAwN_gUy:
просто.
«в Модели» $this->_db->query('всё что хочешь');
«с Моделью»: $table_model->getAdapter()->query('всё что хочешь');

ну и не забываем, что на выходе не Zend_Db_Table_RowSet(Row), а ассоциативный массив.
Вот после таких советов новички начинают «оптимизировать» несколько простых запросов в сложные только чтобы уменьшить абсолютное количество запросов. Ничего хорошего из этого, как правило, не происходит.
«Преждевременная оптимизация — это корень всех бед» © Дональд Кнут
Дональд, наверное, уже сам не рад что сказал эту фразу, настолько часто её приводят в пример.

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

Во вторых, сразу при разработке ставить индексы на поля, по которым делается выборка вы тоже считаете преждевременной оптимизацией? Более того, высокая скорость работы может являться одним из требований к коду. Если вы заранее знаете, что код, будет работать с большими объемами данных, не лишне накидать тестовый данные чтобы посмотреть, а не встанет ли все раком.
Как Вы могли заметить, я обратил внимание не на расстановку индексов, а на поклонение сокращению числа запросов. Само число запросов ни о чем не говорит, но многие начитавшись статей про «оптимизацию» маниакально сокращают это число в ущерб времени выполнения.
плохо не когда запросов много, а когда они без индексов?
>Во вторых, сразу при разработке ставить индексы на поля, по которым делается выборка вы тоже считаете преждевременной оптимизацией?

Если заранее известно, что CUD действий заведомо больше, чем R, то да. Например (под)система логирования
был соблазн перевести как «просрачивание»
просрали все минералы кэши? ;)

Описанные проблемы часто существуют по причине того, что программист может быть хорошим специалистом в php (например), но плохо разбираться в СУБД, отсюда соблазн заткнуть незнание и неумение оптимизировать запросы заглушкой кэширования. Вывод — используешь БД — надо изучить и эту область полностью, либо должен быть отдельный специалист по базам данных, что бывает редко и только в относительно крупных компаниях, насколько я знаю
По-хорошему, должны быть еще разработчики БД и отдельно администраторы БД.
Полимеры!
такое ощущение, что Morgan Tocker (автор) боится кеширования.
> когда в электронном магазине кэш срабатывал для 99% процентов пользователей и не работал для 1%
значит есть кривизна в коде, не надо спирать на кеш
> убегание кэша
если уже выяснили причину, почему бы её не решить?
Этот интернет магазин называется magentocommerce
И реально без кэша оно вообще не работает. С Кэшом как-то приемлемо.
О… Magento это тот еще шедевр)) Пробовал его отпрофилировать xdebug с kcachegrind — лог профилировщика 30Мб получился…
Штука очень тяжелая
Не думаю что он боится. Он просто знает что там залегает много-много граблей.
«когда у Вас есть такой замечательный инструмент как memcached, так и хочется использовать его для решения любой проблемы с производительностью»
Самая распространенная ошибка начинающих — ожидание от кэша того, чего не стоит от него ожидать. Кэширование — это инструмент масштабирования, а не производительности, о чем говорят и сами авторы Memcached.

Ситуация «убегания кэша» в общем случае (не только в случае с кэшем) называется Race Condition (состояние гонки) и с ней есть определенные способы бороться.
Ну я бы сказал это так — убегание кэша — специфическая проблема кэширования данных, с высокой степенью вероятности приводящая к состоянию гонки.
Да, наверное так более правильно.
Memcached это масштабирование памяти, а не просто масштабирование. А память по сравнению с диском это повышение производительности. И кэш != memcached.

«Убегание кеша» называется dog-pile effect.
Memcached — это масштабирование приложения методом использования доступной памяти. Память — да, большая производительность, но это начинает играть роль при высоких нагрузках.

Кэш != memcached — никто об этом и не говорит.

Убегание кэша (dog-pile fx) — частный случай поведения кэша, приводящий к состоянию гонки.
Хм, похоже я не очень ясно выразился.

Кэш — копия данных в быстром хранилище. Это средство повышения производительности. Он применяется во всех слоях, от внутренностях винтов, до самого приложения.

Разработчики memcached писали не о том, что кэширование есть механизм машстабирования, а о том, что Memcached является механизмом маштабирования кэшей.
Вообще, не написали о самом интересном. Почему не стоит сразу «прятаться» за кэширование — из-за селективного удаления кэша. Как было написано в одном источнике:
Warning! Selective Cache Clearing Can damage your Brain.
Мы в случае ORM делали так:
— смотрели, где можно уменьшить количество запросов (часто запросы повторялись, или от многих можно было избавиться с помощью джойнов)
— Забивали базу под завязку, чтобы посмотреть, что будет при большом количестве записей
— А потом для всех тормозящих запросов делали соответствующие улучшения (разбивали на несколько запросов, делали покрывающие индексы и т.д.)

Только после этого можно кэшировать явные сущности (сущность обычно характеризуется одним запросом к БД по первичному ключу) и использовать сфинкс, например.
Горизонтальное масштабирование рулит
во многих вики движках (и некоторых форумах) кеширование страниц делаеться изначально — храниться оригинал текста и рядом его отрендеренный html код.
Там все просто, т.к. легко определить момент инвалидации кэшей.
Статью можно сократить до одного предложения, которое нужно запомнить и повторять, как мантру: «Сначала оптимизируй запросы к БД».
P.S. Это относится только к тому, что из нее надо запоминать. Для понимания, почему это стоит запоминать, статья очень даже нужна.
Имеется в виду, что описанный выше случай — наиболее частый для разработчиков корпоративных приложений. Статья же рассматривает более общий случай.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации