代码之家  ›  专栏  ›  技术社区  ›  Ben Osborne

从S3加载数据-大数据和索引的最快方式

  •  0
  • Ben Osborne  · 技术社区  · 6 年前

    我有一个包含假日交易的表,所以为了给您一个概念,每一行将包含以下数据位:

    Departure airport
    Arrival airport
    Start date
    Duration
    Hotel destination
    Resort
    Hotel name
    Hotel rating
    A few tiny integer columns for 1s and 0s.
    Price
    Date time the row was updated
    

    现在,所有这些交易都是从3张桌子上打包的,它们是 flights , accommodation transfers 包装是为了找到每个变化最便宜的交易,如,每个出发机场,持续时间,董事会的基础等。

    我要导入的表大约有5000万行,导入速度非常慢。

    我已经删除了索引,这有很大的不同,但是现在当我重新将索引添加回表中时,所有数据都在表中,这需要永远完成。

    我想知道有没有一种快速批量加载数据的方法,或者有没有一种在添加数据后更快地将索引添加回表中的方法?

    创建表

    ` `

        CREATE TABLE `iv_deals` (
        `aid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Deal Autonumber PK',
        `startdate` DATE NULL DEFAULT NULL COMMENT 'Holiday Start Date',
        `startdatet` TINYINT(2) NOT NULL DEFAULT '0',
        `depairport` CHAR(3) NULL DEFAULT NULL COMMENT 'Departure Airport IATA Code',
        `arrairport` CHAR(3) NULL DEFAULT NULL COMMENT 'Arrival Airport IATA Code',
        `destination` VARCHAR(30) NULL DEFAULT NULL COMMENT 'Holiday Destination',
        `resort` VARCHAR(30) NULL DEFAULT NULL COMMENT 'Holiday Resort',
        `hotel` VARCHAR(50) NULL DEFAULT NULL COMMENT 'Holiday Property Name',
        `iv_PropertyID` INT(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Holiday Property ID',
        `rating` VARCHAR(2) NULL DEFAULT NULL COMMENT 'Holiday Property Star Rating',
        `board` VARCHAR(10) NULL DEFAULT NULL COMMENT 'Holiday Meal Option',
        `duration` TINYINT(2) UNSIGNED NULL DEFAULT '0' COMMENT 'Holiday Duration',
        `2for1` TINYINT(1) UNSIGNED NULL DEFAULT '0' COMMENT 'Is 2nd Week FREE Offer, 0 = False, 1 = True',
        `3for2` TINYINT(1) UNSIGNED NULL DEFAULT '0' COMMENT 'Is 3rd Week FREE Offer, 0 = False, 1 = True',
        `3and4` TINYINT(1) UNSIGNED NULL DEFAULT '0' COMMENT 'Is 3rd and 4th Week FREE Offer, 0 = False, 1 = True',
        `4for3` TINYINT(1) UNSIGNED NULL DEFAULT '0' COMMENT 'Is 4th Week FREE Offer, 0 = False, 1 = True',
        `freebb` VARCHAR(2) NULL DEFAULT NULL COMMENT 'Free Week Meal Option',
        `adults` TINYINT(1) UNSIGNED NULL DEFAULT '0' COMMENT 'Number of Adults',
        `children` TINYINT(1) UNSIGNED NULL DEFAULT '0' COMMENT 'Number of Children',
        `infants` TINYINT(1) UNSIGNED NULL DEFAULT '0' COMMENT 'Number of Infants',
        `price` SMALLINT(4) UNSIGNED NULL DEFAULT '9999' COMMENT 'Price',
        `carrier` VARCHAR(40) NULL DEFAULT NULL COMMENT 'Flight Carrier IATA Code',
        `DateUpdated` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (`aid`, `startdatet`),
        UNIQUE INDEX `Unique` (`startdate`, `depairport`, `arrairport`, `iv_PropertyID`, `board`, `duration`, `adults`, `children`, `startdatet`),
        INDEX `ik_Price` (`price`),
        INDEX `ik_Destination` (`destination`),
        INDEX `ik_Resort` (`resort`),
        INDEX `ik_DepAirport` (`depairport`),
        INDEX `ik_Startdate` (`startdate`),
        INDEX `ik_Board` (`board`),
        INDEX `ik_FILTER_ALL` (`price`, `depairport`, `destination`, `resort`, `board`, `startdate`),
        INDEX `iv_PropertyID` (`iv_PropertyID`),
        INDEX `ik_Duration` (`duration`),
        INDEX `rating` (`rating`),
        INDEX `adults` (`adults`),
        INDEX `DirectFromPrice` (`iv_PropertyID`, `depairport`, `arrairport`, `board`, `duration`, `adults`, `children`, `startdate`),
        INDEX `DirectFromPrice_wo_depairport` (`iv_PropertyID`, `arrairport`, `board`, `duration`, `adults`, `children`),
        INDEX `DirectFromPrice_w_pid_dep` (`iv_PropertyID`, `depairport`, `adults`, `children`, `price`),
        INDEX `DirectFromPrice_w_pid_night` (`iv_PropertyID`, `duration`, `adults`, `children`),
        INDEX `DirectFromPrice_Dur_Board` (`iv_PropertyID`, `duration`, `board`, `adults`, `children`),
        INDEX `join_index` (`destination`, `startdate`, `duration`)
    )
    COLLATE='utf8_general_ci'
    AUTO_INCREMENT=1258378560
    /*!50100 PARTITION BY LIST (startdatet)
    (PARTITION part0 VALUES IN (1) ENGINE = InnoDB,
     PARTITION part1 VALUES IN (2) ENGINE = InnoDB,
     PARTITION part2 VALUES IN (3) ENGINE = InnoDB,
     PARTITION part3 VALUES IN (4) ENGINE = InnoDB,
     PARTITION part4 VALUES IN (5) ENGINE = InnoDB,
     PARTITION part5 VALUES IN (6) ENGINE = InnoDB,
     PARTITION part6 VALUES IN (7) ENGINE = InnoDB,
     PARTITION part7 VALUES IN (8) ENGINE = InnoDB,
     PARTITION part8 VALUES IN (9) ENGINE = InnoDB,
     PARTITION part9 VALUES IN (10) ENGINE = InnoDB,
     PARTITION part10 VALUES IN (11) ENGINE = InnoDB,
     PARTITION part11 VALUES IN (12) ENGINE = InnoDB,
     PARTITION part12 VALUES IN (0) ENGINE = InnoDB)  */;
    

    ` `

    1 回复  |  直到 6 年前
        1
  •  0
  •   Rick James diyism    6 年前

    如果有50米的排,但是 AUTO_INCREMENT=1258378560 ,让我们指出另一个迫在眉睫的问题。(可能与慢负荷有关。)

    `aid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT
    

    只允许40亿;你已经达到12亿了。做一点数学估计什么时候会用完ID。蛮力解决方案是改为 BIGINT 但是让我们分析一下 为什么 正在“烧掉”这些ID。有几种方法 INSERT / REPLACE /ETC可以丢弃ID。请描述导入的工作方式。 更换 可能是最糟糕的——它烧了身份证 是有效的 DELETE + 插入 . 其他技术更快。

    (我现在将向多个方向漫步…)

    按月份划分(我想你正在做的( startdatet )可能不会增加任何性能。你有什么经验?(我通常反对使用 PARTITION 除了少数有好处的用例。我看不出你的情况有什么好处。)

    19个索引表示必须更新的19个btrees。必须在 插入 完成了;其他17个可以延迟,但不是永远。(详情在“更改缓冲区”下讨论。)

    多少内存?设置是什么 innodb_buffer_pool_size ?它应该是RAM的70%左右。更改缓冲区是其中的一部分。

    我看到至少有4个索引可以删除,因为其他索引可以处理它们的需要。一般来说,如果你有 INDEX(a, b) 你也不需要 INDEX(a) . (从19个指数缩小到15个将有助于 一些 )

    标记和其他低基数的东西在它们本身作为索引时实际上是无用的。优化器将决定扫描表比在索引的btree和数据btree之间跳转便宜。我在想 INDEX(rating)

    任何 SELECT 是的。 开始日期 WHERE 很可能是 更慢的 比没有分区要好。这是因为查询必须检查所有13个分区。即使有 AND startdatet = 4 ,性能不会比包含startdatet的索引更好。

    我来讨论一下指数 启动 有一列(也许 price , rating , startdate )作为“范围”查询(例如, WHERE price BETWEEN ... )处理不能在该列之后使用任何列。我怀疑 ik_FILTER_ALL 将扫描索引的一大块,因为它只筛选 价格 . 重新排列列。根据名字,我猜这是一个“覆盖”索引。也就是说,公共查询只引用这6列?注: SELECT * ... 引用的不仅仅是这6个,所以索引不是“覆盖”。(向我们展示这个问题;我可以进一步讨论。)

    5个“directfromprice”索引对于某些查询可能都是“完美的”。但是它们非常长(很多列)。我会的 猜测 这两个较短的列表将接近于“足够好地”处理这5个案例。(记住,减少索引的数量将有助于实现插入时间的目标。)

    您使用的是什么版本的mysql/mariadb?

    此时的主要操作项:显示导入。(我将在看到使用的方法后讨论对输入进行排序。)