从S3加载数据-处理大数据和索引的最快方法

时间:2018-08-24 12:46:54

标签: mysql amazon-s3 bigdata

我有一个包含假期交易的表格,所以为了给您一个主意,每一行将包含以下数据:

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个表中打包,分别是flightsaccommodationtransfers,打包后可以找到每个变体中最便宜的交易,例如,每个出发机场,飞行时间,登机时间等。

我要导入的表将包含大约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 个答案:

答案 0 :(得分:0)

如果有5000万行,但是AUTO_INCREMENT=1258378560,请指出另一个迫在眉睫的问题。 (这可能与负载缓慢有关。)

`aid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT

只允许40亿;您已经达到了12亿。做一点数学来估计何时将用完ID。蛮力解决方案是更改为BIGINT,但让我们分析为什么标识被“刻录”。 INSERT / REPLACE / etc有几种丢弃ID的方法。请描述导入的工作方式。 REPLACE可能是最糟糕的-它会烧录 id ,实际上是DELETE + INSERT。其他技术更快。

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

按月分区(我假设您正在使用(startdatet)可能不会增加任何性能。您的经验如何?(除了少数几个,我通常反对使用PARTITION有好处的用例。我认为您没有用。)

19个索引表示必须更新的19个BTree。 INSERT完成之前必须检查2个唯一性;其他17个可以延迟,但不能永远延迟。 (有关详细信息,请参见“更改缓冲区”。)

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

我看到至少可以删除4个索引,因为其他索引可以处理它们的需求。通常,如果您有INDEX(a, b),则也不需要INDEX(a)。 (将19个索引缩小到15个将对 some 有所帮助。)

标记和其他低基数的东西实际上对它们本身毫无用处。优化程序将决定扫描表比在索引的BTree和数据BTree之间反弹要便宜。我在考虑INDEX(rating)

没有{em> 在SELECT中具有startdatet的任何WHERE可能比没有分区的。这是因为查询必须检查所有13个分区。即使使用AND startdatet = 4,性能也不会比有包含startdatet的索引更好。

让我讨论以“范围”查询的列(也许是priceratingstartdate(例如,WHERE price BETWEEN ...ik_FILTER_ALL price)。处理不能使用该列之后的任何列。我怀疑SELECT * ...将扫描索引的很大一部分,因为它仅在[Export(typeof(IMyViewHost))] public class MyViewHost : IMyViewHost { [Import] public ITextEditorFactoryService TextEditorFactory { get; set; } public IWpfTextViewHost CreateViewHost(ITextBuffer textBuffer) { var textView = this.TextEditorFactory.CreateTextView(textBuffer); return this.TextEditorFactory.CreateTextViewHost(textView, true); } 上进行了过滤。重新排列列。基于名称,我猜这是一个“覆盖”索引。也就是说,一个普通查询仅引用这6列?注意:IMyViewHost引用的不仅仅是6个索引,因此索引不是“ covering”。 (向我们显示查询;我可以对其进行更多讨论。)

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

您使用的是哪个版本的MySQL / MariaDB?

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