在 mysql 的定价表中连续(重新)导入和刷新数据



我有一个大型数据集(~250万行(,需要(重新(连续地导入MySQL表"price_list"。所有表都是InnoDB。目前我正在使用"加载数据本地文件",因为这些数据集来自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€                 | ...
(...)

基于这些数据,我需要更新表"报价"(该表位于另一个数据库中,用户"price_list"无法访问"报价",并且在技术上不可能提供适当的访问权限(刷新定价。定价变化很大,我们需要每 15 分钟重新导入一次这些数据。

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

在上面的例子中,选择了"最佳"单人间(带漩涡浴缸(的价格(200欧元(。此优惠中不需要第二个价格,但这是故意计算的(如果需要,可以停用(。

我目前的解决方案是我从 PHP 的"offer"表中获取所有报价,这些报价被标记为活动,并循环访问它们 (oof(。每个报价都有 6 列不同的价格(例如,酒店有不同的房间可用;第 1 列是单人间的最优惠价格,第 2 列是双人间的最优惠价格,...(,需要查找。

目前我们有大约 10.000 个活动报价,这意味着我向数据库服务器发送以下数量:10.000 个查询 * 6 个查询,用于查找每个报价的最佳定价。

当我在同一台服务器上执行这些查询(没有网络延迟等(时,性能并不是最差的(整个工作大约需要 5 分钟(导入 ~2.5m 行,刷新定价,...((,但由于数据在增长,我们希望拆分数据库和 Web 服务器。我现在意识到,我刷新价格的部分会产生大量的网络开销,并且非常慢,因为从 web 服务器到 db 服务器的每个请求大约需要 0.025 秒(仅刷新价格需要 25 分钟(。

我想到了以下解决方案:

  • 将表"提供"移动到同一数据库 "price_list" = 工作,但仍然很慢,因为数据库服务器与 Web 服务器不在同一台机器上 = 网络延迟是瓶颈。

  • 编写一个存储过程,该过程由 PHP 触发,数据库服务器将完成该工作。

是否有人有这些重复数据加载的经验,也许是我给定问题的解决方案?目标是减少计时并拆分 Web 和数据库服务器。

谢谢!

您有一个名为 'real 的表;以下内容将用包含新数据的新表替换它。

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

最新更新