Обработка тысяч записей в MySQL

Я думаю, лучший способ - использовать ether_ntoa (), который доступен практически для любой операционной системы * nix (доступной в net / ethernet.h). Для меня это хорошо работает.

char *addr;
struct ether_addr host;

memcpy(&host, ethernet->ether_dhost, sizeof(host));
addr = ether_ntoa(&host);
0
задан user538578964 18 March 2019 в 18:35
поделиться

2 ответа

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

Так что все, что ваш фрагмент кода:

$properties = Property::where('status', 'Active');
foreach($properties as $property) { // 100+ times
     $bookings = Booking::where('status', 'Approved')->where('checked_in', 1)->where('propId', $property->id)->get();
     $commission = 0.0; // commissions owed to us
     $commissionOta = 0.0; // any commissions owed to OTA's
     foreach($bookings as $booking) { // 2000+ times
          $commission += $booking->commission;
          $commissionOta += $booking->commissionOta;
     }
     $totalReceived = PaymentReceived::where('propId', $property->id)->sum('amount'); // any amounts paid by the property owner
     $property->payable = ($commission + $commissionOta) - $totalReceived;
}

Кажется, равны только этому запросу:

SELECT p.id,
       SUM(b.commission) s_comm,
       SUM(b.commissionOta) s_commOta,
       SUM(b.commission) + SUM(b.commissionOta) - pr.amount payable
FROM Property p
INNER JOIN Booking b
ON b.propOd = p.id
  AND b.status = 'Approved'
  AND checked_in = 1 
LEFT JOIN (
    SELECT pr.propId, SUM(pr.amount) amount
    FROM PaymentReceived pr
    GROUP BY pr.propId
) pr
ON pr.propId = p.id
WHERE p.status = 'Active'
GROUP BY p.id

Попробуйте выполнить этот запрос. Проверьте набор результатов и производительность и попробуйте адаптировать свой код для использования одного запроса вместо циклических запросов к БД.

Для Laravel это должно быть что-то вроде:

$result = DB::select('SELECT p.id,
       SUM(b.commission) s_comm,
       SUM(b.commissionOta) s_commOta,
       SUM(b.commission) + SUM(b.commissionOta) - pr.amount payable
FROM Property p
INNER JOIN Booking b
ON b.propOd = p.id
  AND b.status = \'Approved\'
  AND checked_in = 1 
LEFT JOIN (
    SELECT pr.propId, SUM(pr.amount) amount
    FROM PaymentReceived pr
    GROUP BY pr.propId
) pr
ON pr.propId = p.id
WHERE p.status = \'Active\'
GROUP BY p.id');

foreach($result as $r){
    echo 'Property id: '.$r->id.' Commission: '.$r->s_comm. ' Commission Ota: '.$r->commissionOta .' Payable: '.$r->payable ;
}

Другая идея, которую вы должны попытаться реализовать, - сократить / закрыть период . Прямо сейчас, если я правильно понимаю, вы пересчитываете все данные с самого начала каждого месяца или какого-либо другого периода. Но, как правило, вам следует сохранять некоторые сбалансированные результаты за предыдущий период и пересчитывать только разницу на основе данных за последний период.

0
ответ дан Alex 18 March 2019 в 18:35
поделиться

Ну, у меня есть некоторый опыт работы с «большими данными» (ну, не такой большой, но не маленький - я работаю в сфере телекоммуникаций, и у меня есть таблица сведений о вызовах, которая часто превышает 200 тыс. Записей). Я могу вам сказать, что при правильной индексации поиски выполняются довольно быстро. Я только что провел тест в таблице со 116803 строками в неиндексированном столбце и получил результат:

Showing rows 0 - 24 (1608 total, Query took 0.0016 seconds)

Теперь, в той же таблице, в индексированном столбце:

Showing rows 0 - 0 (1 total, Query took 0.0008 seconds.)
[116 ] Кроме того, если вы используете соединения (слева, справа, внутри и т. Д.), Они должны быть в индексированных столбцах. Таким образом, sql не должен искать всю объединенную таблицу для каждой строки.

Итак, если у вас есть следующий запрос:

SELECT * FROM table_a INNER JOIN table_b ON column_from_a = column_from_b

убедитесь, что column_from_b проиндексирован, если table_b довольно большой.

Другая вещь (но немного более сложная) - это репликация. Вы можете иметь кластер SQL с, скажем, 3 сервера. Вы можете настроить основные приложения на использование двух из них, а третье зарезервировать для интенсивной работы.

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

0
ответ дан Cosmin Staicu 18 March 2019 в 18:35
поделиться
Другие вопросы по тегам:

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