Огромный непрерывный (ре) импорт и обновление sh данных в таблице цен в mysql - PullRequest
1 голос
/ 28 января 2020

У меня большой набор данных (~ 2,5 миллиона строк), который необходимо (повторно) постоянно импортировать в MySQL таблицу «price_list». Все таблицы InnoDB. В настоящее время я использую «LOAD DATA LOCAL INFILE», потому что эти наборы данных взяты из CSV-файлов:

LOAD DATA LOCAL INFILE 'sample.csv'
INTO TABLE `price_list`
(...)
(...)
IGNORE 1 LINES

Пример таблицы в db «price_list»:

hotel_id | room_category            | price 1 person | price 2nd person     | <other meta info>

1        | single room (w/o window) | 150€           | 200€                 | ...
2        | single room (w window)   | 170€           | 220€                 | ...
3        | single room (rooftop)    | 240€           | 250€                 | ...
4        | single room (whirlpool)  | 200€           | 280€                 | ...
5        | double room (w/o window) | 200€           | 220€                 | ...
6        | double room (w window)   | 240€           | 260€                 | ...
7        | double room (rooftop)    | 280€           | 300€                 | ...
8        | double room (whirlpool)  | 320€           | 340€                 | ...
(...)

На основе на этих данных мне нужно обновить таблицу «предложения» (таблица находится в другой базе данных, у пользователя нет «прайс-листа», нет доступа к «предложениям» и технически невозможно предоставить надлежащий доступ) с обновленными ценами. Цены сильно меняются, и мы должны повторно импортировать эти данные каждые 15 минут.

id  |       offer_name           |   price_single_room    |    price_double_room
1   |  WHIRLPOOL OFFER SINGLES   |         200€           |          200€

В приведенном выше примере была выбрана цена за «лучший» одноместный номер (с гидромассажем) (200 €). Вторая цена не требуется в этом предложении, но рассчитывается специально (и может быть отключена при желании).

Мое текущее решение состоит в том, что я получаю все предложения из таблицы «предложений» в PHP, которые помечены как активные, и через них l oop ( oof ). Каждое предложение имеет 6 столбцов для разных цен (например, в отеле есть разные доступные номера; столбец 1 - лучшая цена за одноместный номер, столбец 2 - лучшая цена за двухместный номер, ...), который необходимо найти.

В настоящее время у нас около 10.000 активных предложений, что означает, что я отправляю на сервер базы данных следующую сумму: 10.000 запросов * 6 запросов для поиска лучших цен на предложение.

Когда я выполняю эти запросы на одном и том же сервере (без задержек в сети и т. Д. c), производительность не самая плохая (вся работа занимает около 5 минут (импорт ~ 2,5 м строк, refre sh) цены, ...)), но так как данные растут, мы хотим разделить базу данных и веб-сервер. Теперь я понял, что та часть, в которой я обновляю цены, создает большие накладные расходы с сетью и очень медленная, поскольку каждый запрос от веб-сервера к серверу БД занимает около 0,025 с (25 минут только для обновления цен).

Я подумал о следующих решениях:

  • переместить таблицу «предложения» в ту же базу данных «price_list» = работает, но все еще очень медленно, так как сервер базы данных не находится на Узким местом является тот же компьютер, что и веб-сервер = задержка в сети.

  • написать хранимую процедуру, которая запускается PHP, и сервер базы данных выполняет эту работу.

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

Спасибо!

1 Ответ

0 голосов
/ 05 февраля 2020

У вас есть таблица с именем `real; следующий заменит его новой таблицей, содержащей данные fre sh.

CREATE TABLE t_new LIKE real;
LOAD DATA INFILE new ...;
RENAME TABLE real TO t_old,
             t_new TO real;
DROP TABLE t_old;

Примечания:

⚈  The LOAD DATA step can be replaced by whatever process you have for importing the data.
⚈  The Loading is the only slow step.
⚈  The RENAME is atomic, so real always exists.
⚈  You may choose to delay the DROP in case the new data might be bad and you want to revert.
⚈  FOREIGN KEYs can be a hassle; it might be good not to have such.

- http://mysql.rjweb.org/doc.php/deletebig#optimal_reload_of_a_table

...