Оптимизация MySQL CREATE TABLE Query - PullRequest
0 голосов
/ 01 марта 2019

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

Вот синтаксис, который я использую

CREATE TABLE active_users
(PRIMARY KEY ix_all (platform_id, login_year, login_month, person_id))
SELECT platform_id
    , YEAR(my_timestamp) AS login_year
    , MONTH(my_timestamp) AS login_month
    , person_id
    , COUNT(*) AS logins
FROM
    my_login_table
GROUP BY 1,2,3,4;

CREATE TABLE active_alerts
(PRIMARY KEY ix_all (platform_id, alert_year, alert_month, person_id))
SELECT platform_id
    , YEAR(alert_datetime) AS alert_year
    , MONTH(alert_datetime) AS alert_month
    , person_id
    , COUNT(*) AS alerts
FROM 
    my_alert_table
GROUP BY 1,2,3,4;

CREATE TABLE all_data
(PRIMARY KEY ix_all (platform_id, theYear, theMonth, person_id))
SELECT a.platform_id
    , a.login_year AS theyear
    , a.login_month AS themonth
    , a.person_id
    , IFNULL(a.logins,0) AS logins
    , IFNULL(b.alerts,0) AS job_alerts
FROM
    active_users a
LEFT OUTER JOIN
    active_alerts b
        ON a.platform_id = b.platform_id
        AND a.login_year = b.alert_year
        AND a.login_month = b.alert_month
        AND a.person_id = b.person_id;

ПерваяТаблица (входы в систему) возвращает около полумиллиона строк и занимает менее 1 минуты, вторая таблица (предупреждения) возвращает около 200 тыс. строк и занимает менее 1 минуты.

Если я запускаю только часть SELECT третьего оператора, он выполняется через несколько секунд, однако, как только я запускаю его с синтаксисом CREATE TABLE, это занимает более 30 минут.

Iпробовал индексы других типов, отличные от первичного ключа, такие как UNIQUE или INDEX, а также вообще без ключа, но, похоже, это не имеет большого значения.

Есть ли что-то, что я могу сделать, чтобы ускоритьсоздание / вставка этой таблицы?

РЕДАКТИРОВАТЬ: Вот выходные данные операторов show create table

CREATE TABLE `active_users` (
  `platform_id` int(11) NOT NULL,
  `login_year` int(4) DEFAULT NULL,
  `login_month` int(2) DEFAULT NULL,
  `person_id` varchar(40) NOT NULL,
  `logins` bigint(21) NOT NULL DEFAULT '0',
  KEY `ix_all` (`platform_id`,`login_year`,`login_month`,`person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

CREATE TABLE `alerts` (
  `platform_id` int(11) NOT NULL,
  `alert_year` int(4) DEFAULT NULL,
  `alert_month` int(2) DEFAULT NULL,
  `person_id` char(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
  `alerts` bigint(21) NOT NULL DEFAULT '0',
  KEY `ix_all` (`platform_id`,`alert_year`,`alert_month`,`person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

и выходные данные EXPLAIN

id  select_type table   partitions  type    possible_keys   key key_len ref rows    filtered    Extra

1   SIMPLE  a   (null)  ALL (null)  (null)  (null)  (null)  503504  100 (null)

1   SIMPLE  b   (null)  ALL ix_all  (null)  (null)  (null)  220187  100 Using where; Using join buffer (Block Nested Loop)

1 Ответ

0 голосов
/ 01 марта 2019

Это что-то вроде хака, но я понял, как заставить его работать намного быстрее.

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

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

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