Задать вопрос
@maiskiykot
Free coder

Почему тормозит код записи в MySQL после разбивки его на функции?

Создал функцию save_product для записи товаров в базу. Для удобства и наглядности раскидал запись в каждую таблицу по функциям и... получил жуткие тормоза! Одна запись выходила по 16 секунд! Т.е. save_product вызывал save_category с проверкой check_category, save_brand и save_image. Не поленился - проверил тайминг внутри функций - все по нолям! А вызов из функции save_product - до 8 секунд доходил! В чем причина такого поведения и как избежать простыни кода в функции save_product для ускорения всей процедуры?
  • Вопрос задан
  • 398 просмотров
Подписаться 4 Простой 2 комментария
Пригласить эксперта
Ответы на вопрос 5
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Если вы делаете коннект к БД в каждой функции, то результат логичен. Коннект занимает в лучшем случае 0.2-0.5 секунды, в худшем - несколько секунд.
Используйте внедрение зависимости, подключайтесь к базе один раз с начале скрипта и передавайте подключение в экземпляр класса при его создании. Или по старинке используйте синглтон.
Ответ написан
@rPman
хоть один пример такой функции показал бы

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

p.s. гугли - php профилирование вызовов функций
Ответ написан
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Во-первых, такой подход называется не функциональным, с процедурным. Функциональное программирование - это совсем другое.
Во-вторых, сама по себе разбивка кода на функции ни к какому замедлению не приводит.
Проблема не в том, что много функций, а в том коде, который в них написан.

В целом, цифры какие-то дикие. Что 8 секунд, что 16, что 3. Для записи одного "продукта" нужно максимум 0.1 секунды, если всё очень сильно тормозит
Ответ написан
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
Вот к примеру была функция check_category - вообще ничего не записывала:
$sql = "SELECT category_id,name FROM {$prefixTables}category_description WHERE name='".iconv('UTF-8', 'UTF-8', trim($str['category']))."'";

$res = $pdo->query($sql);

while($row = $res->fetch())
{
$category_id = $row['category_id'];
}

Это вы на каждый параметр делаете проверку таким образом, да? Ну тогда все логично, вместо одного запроса в бд у вас их много, вот и выходит лажа. То что она ничего не записывала не отменяет нагрузку на базу. База вообще самое узкое место практически всегда, по этому в базу нельзя лазить когда вздумается. Сделал 1 раз выборку всех нужных данных и с этим массивом работаешь.
Ответ написан
mayton2019
@mayton2019
Bigdata Engineer
раскидал запись в каждую таблицу по функциям


Подобного рода рефакторинги надо сопровождать кодом. Наиболее вероятный вариант - ты создаешь отдельный connection в каждой функции. Так делать не надо. Второй вариант - ты играешся с коллекциями там где нужны курсоры. Третий вариант - транзакции и блокировки но все это надо смотреть в твой код.

Не мучай пожалуйста нас эпистолярным жанром. Давай код в студию едрён-батон...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы