3 частые проблемы производительности веб-приложений, первая проблема

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

Дорогие запросы к базе данных внутри цикла.

Самый банальный пример и очень часто встречающийся паттерн в коде. Мы получаем откуда-то айдишники строк в БД (это может быть что угодно, перечень товаров на главной, содержимое корзины, номера статей с лайками пользователя) и далее по этим номерам делаем запросы и собираем массив/коллекцию:

Во-первых, тут присутствует красный флаг, о которым я писал ранее (https://dmitriynyu.com/perfomance-testing/) — нет ограничения на количества шагов в цикле. Код написан так, что мы вынуждены надеется, что количество айдишников, которое вернёт getIdsOfItemsInCart() будет небольшим, но на самом деле, мы этого точно не знаем.

Во-вторых, этот паттерн очень ловко маскируется. У вас в коде он может существовать не в таком явном виде, как в примере выше, это может быть например прикрепление свойств товара в интернет магазине к номенклатурной позиции. Менеджер добавил о 100 свойств к каждой детской игрушке — цвет, вес, форма и т.д., и теперь при каждом простом запросе вроде:

самописная и не очень умная ОРМ в глубине модели Item совершает 100 отдельных запросов к этим свойствам (это реальный случай).

В-третьих, этот вредный паттерн очень легко недооценить и проигнорировать. Например, внутри метода Item::first() может происходит кеширование. Полагаясь на это, вы подвергаете себя риску низкого быстродействия в случае, когда вдруг кэшу не хватит памяти и он решит почистить эти записи. Вполне реальна ситуация, когда в начале метод в цикле просто возвращал захардкоденные значения, а потом этот метод порефакторили, и он стал обращаться к базе. А про то, что метод вызывается до 100 раз в цикле, все забыли или не проверили.

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


Also published on Medium.

3 частые проблемы производительности веб-приложений, первая проблема: 1 комментарий

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