ЗАГРУЗКА ДАННЫХ ИЗ S3 - Самый быстрый способ для больших данных и индексов - PullRequest
0 голосов
/ 24 августа 2018

У меня есть таблица, которая состоит из праздничных предложений, так что просто чтобы дать вам представление, каждая строка будет содержать следующие биты данных:

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, упаковка состоит в том, чтобы найти самую дешевую сделку для варианта, например, для аэропорта вылета, продолжительности, доска и т. д.

Таблица, в которую я импортирую, будет содержать около 50 миллионов строк, импорт очень медленный.

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

Хотелось бы узнать, есть ли способ быстрой загрузки данных или более быстрый способ добавления индексов в таблицу после добавления данных?

Создать таблицу

`` `

    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 голосов
/ 30 августа 2018

Если есть 50M строк, но AUTO_INCREMENT=1258378560, позвольте указать на другую проблему, которая надвигается.(Это может быть связано с медленной загрузкой.)

`aid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT

допускает только 4 миллиарда;вы уже на 1,2 миллиарда.Сделайте небольшую математику, чтобы оценить, когда у вас закончатся идентификаторы.Решение для перебора - изменить BIGINT, но давайте проанализируем , почему идентификаторы «сжигаются».Есть несколько способов, которыми INSERT / REPLACE / etc могут выбрасывать идентификаторы.Пожалуйста, опишите, как работает импорт.REPLACE, пожалуй, худший - он сжигает идентификаторы и эффективно DELETE + INSERT.Другие методы работают быстрее.

(теперь я буду бродить по многим направлениям ...)

Разделение по месяцам (которое я предполагаю, что вы делаете с (startdatet), вероятно, не добавляетлюбой результат. Каков ваш опыт? (Я обычно не согласен с использованием PARTITION, за исключением нескольких случаев использования, где есть преимущества. Я не вижу никакой выгоды в вашем случае.)

19 индексов означает 19 B, чтодолжны быть обновлены. 2 уникальных должны быть проверены до окончания INSERT, 17 других могут быть отложены, но не навсегда (подробности обсуждаются в разделе «буфер изменений».)

СколькоОЗУ? Какая настройка innodb_buffer_pool_size? Она должна составлять около 70% ОЗУ. Часть изменения - это буфер.

Я вижу как минимум 4 индекса, которые можно отбросить, так как другие индексы обрабатываюткак правило, если у вас есть INDEX(a, b), вам также не нужно INDEX(a). (Сокращение с 19 индексов до 15 поможет немного .)

Флаги и другиевещи с низким уровнем мощности практическибесполезны сами по себе в качестве указателей.Оптимизатор решит, что сканировать таблицу дешевле, чем отскок между BTree индекса и данными BTree.Я думаю о INDEX(rating).

Любой SELECT, который не имеет startdatet в WHERE, вероятно, будет медленнее , чем безсекционирования.Это потому, что запрос должен проверить все 13 разделов.Даже с AND startdatet = 4 производительность не будет лучше, чем если бы существовал индекс, включающий startdatet.

Позвольте мне обсудить любой индекс начиная с со столбцом (возможно, price), rating, startdate), который запрашивается как «диапазон» (например, WHERE price BETWEEN ...).Обработка не может использовать столбцы после этого столбца.Я подозреваю, что ik_FILTER_ALL будет сканировать большую часть индекса, поскольку он фильтруется только по price.Переставьте колонки.Основываясь на названии, я предполагаю, что это «покрывающий» индекс.То есть общий запрос ссылается только на те 6 столбцов?Примечание: SELECT * ... ссылается не только на эти 6, поэтому индекс не является "покрывающим".(Покажите нам запрос; я могу обсудить его подробнее.)

Каждый из 5 индексов "DirectFromPrice", вероятно, "идеален" для какого-то запроса.Но они ужасно длинные (много столбцов).Я бы предположил , что 2 более коротких списка приблизились бы к обработке 5 дел "достаточно хорошо".(Помните, что уменьшение количества индексов поможет увеличить время вставки.)

Какую версию MySQL / MariaDB вы используете?

Основной элемент действия на этом этапе: показать намимпорт.(Я буду обсуждать сортировку ввода после просмотра используемого метода.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...