fbpx
Оптимизация не всегда оптимизирует…

оптимизация

Решил поделиться одной маленькой, но очень интересной технической историей. Представьте себе очень большую табличку в базе данных (сотни миллионов записей). Все записи разделены на пачки, у каждой записи есть ссылка на идентификатор пачки. В пачке может быть от сотен до миллионов записей. Вот такая вот простая предыстория. 🙂

В один прекрасный день понадобилось сделать опцию для вычитки, преобразования и переноса записей в другую систему. Причем для конкретных пачек, которые задаются в момент экспорта. И записи нужны не все, а только “хорошие”. Критерий “хорошести” был очень прост: статус записи не равен ‘F’. Разработчик подумал-подумал и решил проверить сколько записей отсекается этим критерием. Оказалось что от 10% до 30%. Можно ведь неплохо сэкономить, вычитывая только “хорошие” записи! Сказано – сделано! Фильтрующий запрос, индекс в базе чтобы работало пошустрее и все рады.

Прошло немного времени и экспортом стали активно пользоваться. Критерий “хорошести” очень быстро обретал все новые и более сложные формы. Теперь уже сравнивались между собой несколько полей записи и статусы проверялись более расширенно. Естественно, мигрировал он от простого к сложному не сразу, а постепенно. При этом, глобальное решение не менялось, а просто менялся запрос к базе данных и тюнились индексы. Все продолжало работать достаточно шустро и радовало заказчика. 🙂

И тут неожиданно кто-то решил экспортировать очень большую пачку, в которой было больше 10 миллионов записей. Экспорт продолжался 12 часов и не планировал завершаться. Все были удивлены подобным результатом. Ведь запрос на вычитку одной страницы записей работал достаточно шустро и механизм экспорта был линейным. Анализ запроса также показал, что все шло по плану – использовались нужные индексы и все сделано оптимально. Экспоненциального роста времени выполнения ожидать было неоткуда. В чем же дело?

Оказалось, что все достаточно просто – базе данных этот запрос давался легко и непринужденно, когда записей в пачке было немного (до 100K). На миллионе записей ситуация становилась чуть хуже, но лишь чуть-чуть. А вот начиная с 5 миллионов, все начинало деградировать очень сильно. Возможно “прочесывание” индекса становилось сложнее или постоянная подгрузка и выгрузка данных в память начинала притормаживать. Это не так важно. Изначальное решение никто на таком объеме не проверял по простой причине – не было требований поддерживать такие большие пачки…

Но делать что-то надо было. После недолгого анализа решено было попробовать делать фильтрацию на “клиентской” части (в коде экспорта), при этом вычитывать все записи из пачки. Какой был результат? Экспорт пачки завершился за минуту. Разница не в 10 и не в 100 раз. Почему так произошло? Для фильтрации записей по пачке используется самый популярный и легковесный индекс, который часто используется и постоянно находится целиком в памяти. Дальше записи вычитываются по первичному ключу, что является самой быстрой операцией в базе данных. А фильтрация отнимает в коде мизерное время.

Давайте проанализируем результаты. Да, после наших действий увеличился объем передаваемых данных с базы на клиента (на те самые 10-30%). Зато мы разгрузили базу очень сильно по памяти и дисковой активности. Мало того, мы убрали на нашем пути одну из преград для использования в целях данной операции NoSQL решений. Нет фильтрующего запроса и можно еще больше оптимизировать работу, используя хотя бы NoSQL клиента для MySQL. База данных является узким местом в современных распределенных приложениях и ее надо разгружать всеми силами.

Для чего я рассказал эту историю? Ради двух выводов:

  • Не всякая логически правильная оптимизация является оптимизацией и все нужно измерять для принятия решения.
  • Любое существующее решение должно подвергаться критике и сомнениям при изменении требований к данному решению. Не бойтесь менять решения!

Оптимизируйте с умом! 🙂

Не хочешь пропускать ничего интересного? Подпишись на ленту RSS или следи за нами в Twitter!

Обсуждение (
Warning: A non-numeric value encountered in /sata1/home/users/xpinjecti/www/www.xpinjection.com/wp-includes/pomo/plural-forms.php on line 280

Warning: A non-numeric value encountered in /sata1/home/users/xpinjecti/www/www.xpinjection.com/wp-includes/pomo/plural-forms.php on line 280

Warning: A non-numeric value encountered in /sata1/home/users/xpinjecti/www/www.xpinjection.com/wp-includes/pomo/plural-forms.php on line 280

Warning: A non-numeric value encountered in /sata1/home/users/xpinjecti/www/www.xpinjection.com/wp-includes/pomo/plural-forms.php on line 280

Warning: A non-numeric value encountered in /sata1/home/users/xpinjecti/www/www.xpinjection.com/wp-includes/pomo/plural-forms.php on line 280

Warning: A non-numeric value encountered in /sata1/home/users/xpinjecti/www/www.xpinjection.com/wp-includes/pomo/plural-forms.php on line 280
1)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

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

принять