Для каждого запроса вставки лучший способ

Вопрос или проблема

Здравствуйте, у меня есть этот код, который работает нормально, но я думаю, что он использует много ресурсов сервера, потому что выполняется запрос к базе данных для каждого идентификатора пользователя, хранящегося в группе. Есть ли способ решить эту проблему? Также как я могу использовать подготовленные выражения?

$event_start_date = date('d-m-Y', strtotime($new_start_date));
    $notification = "Новое событие <span class="text-warning"><strong>$event_title</strong></span> начинается $event_start_date";
    $notification_status = "0";
    $notification_category= "events";


    $sql = "SELECT user_join_id FROM user_group_join WHERE group_join_id='$event_group'";

    $result= mysqli_query($conn,$sql);

    $datas= array();

    if(mysqli_num_rows($result) > 0){

        while($row=mysqli_fetch_array($result, MYSQLI_ASSOC)){

        $datas[]= $row;

        }

    }

    foreach($datas as $data) {

    $id_cliente = $data['user_join_id'];

    $event_notification = mysqli_prepare($conn, "INSERT INTO user_notifications (notification_sent_by, notification_sent_to, notification_message, notification_time, notification_status, notification_category, notification_category_id) VALUES(?,?,?,now(),?,?,?)");
    mysqli_stmt_bind_param($event_notification, 'iisisi', $userid, $id_cliente, $notification, $notification_status, $notification_category, $event_id);
    mysqli_stmt_execute($event_notification);
    mysqli_stmt_close($event_notification);

    }

Большое спасибо за вашу помощь

Кроме того, вы подготавливаете выражение, используете его и затем закрываете на каждом шаге цикла. Это много потраченных усилий.

Подготовьте один раз, используйте в цикле, а затем закройте в конце.

$event_notification = mysqli_prepare($conn, "INSERT INTO user_notifications (notification_sent_by, notification_sent_to, notification_message, notification_time, notification_status, notification_category, notification_category_id) VALUES(?,?,?,now(),?,?,?)");
foreach($datas as $data) {
    $id_cliente = $data['user_join_id'];
    mysqli_stmt_bind_param($event_notification, 'iisisi', $userid, $id_cliente, $notification, $notification_status, $notification_category, $event_id);
    mysqli_stmt_execute($event_notification);
}
mysqli_stmt_close($event_notification);

Я ожидаю, что это будет значительно быстрее.

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

Этот ответ на SO предлагает мне это, в любом случае. Учитывая, что вы уже построили большой массив, вы должны иметь возможность использовать его без foreach, чтобы не разбивать его обратно. Это может быть даже быстрее.

Ответ или решение

В вопросе, который вы подняли, заключается важная задача оптимизации запросов к базе данных в контексте использования языка программирования PHP с расширением mysqli. Сначала давайте рассмотрим текущую структуру кода, а затем предложим улучшения, которые помогут уменьшить нагрузку на сервер и ускорить выполнение операций с базой данных.

Анализ текущего кода

Исходя из предоставленного вами образца кода, мы видим, что вы выполняете выборку идентификаторов пользователей из таблицы user_group_join, а затем, используя цикл foreach, добавляете уведомления для каждого пользователя, выполняя при этом подготовленный SQL-запрос.

Проблемы текущего подхода:

  1. Множественные запросы к базе данных: Для каждого идентификатора пользователя создается новый запрос к базе данных, что существенно увеличивает время выполнения и создает ненужную нагрузку на сервер.
  2. Подготовка и закрытие запроса внутри цикла: Каждый раз, когда вы вызываете mysqli_prepare и mysqli_stmt_close, вы тратите дополнительные ресурсы.

Оптимизация процесса вставки уведомлений

1. Подготовка одного запроса

Как вы правильно заметили, подготовленный запрос следует создавать вне цикла, а использовать его многократно внутри цикла. Таким образом, мы уменьшаем количество подготовительных операций.

Вот ваш оптимизированный код:

$event_start_date = date('d-m-Y', strtotime($new_start_date));
$notification = "Nuovo evento <span class='text-warning'><strong>$event_title</strong></span> inizia il $event_start_date";
$notification_status = "0";
$notification_category= "events";

$sql = "SELECT user_join_id FROM user_group_join WHERE group_join_id=?";
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, 'i', $event_group);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);

$datas = array();
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    $datas[] = $row;
}
mysqli_stmt_close($stmt);

if (!empty($datas)) {
    // Подготовка единственного сообщения
    $event_notification = mysqli_prepare($conn, "INSERT INTO user_notifications (notification_sent_by, notification_sent_to, notification_message, notification_time, notification_status, notification_category, notification_category_id) VALUES(?, ?, ?, NOW(), ?, ?, ?)");

    foreach ($datas as $data) {
        $id_cliente = $data['user_join_id'];
        mysqli_stmt_bind_param($event_notification, 'iisisi', $userid, $id_cliente, $notification, $notification_status, $notification_category, $event_id);
        mysqli_stmt_execute($event_notification);
    }

    mysqli_stmt_close($event_notification);
}

2. Пакетная вставка данных

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

Вы можете использовать следующий подход:

if (!empty($datas)) {
    $sql_values = [];
    foreach ($datas as $data) {
        $id_cliente = $data['user_join_id'];
        $sql_values[] = "($userid, $id_cliente, '$notification', NOW(), '$notification_status', '$notification_category', $event_id)";
    }

    // Формируем финальный SQL запрос
    $sql_insert = "INSERT INTO user_notifications (notification_sent_by, notification_sent_to, notification_message, notification_time, notification_status, notification_category, notification_category_id) VALUES " . implode(',', $sql_values);

    mysqli_query($conn, $sql_insert);
}

Заключение

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

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

Капча загружается...