Mysql аннотированная таблица с агрегированной суммой - PullRequest
0 голосов
/ 02 октября 2018

У меня есть две таблицы, которые выглядят так:

t1
alias_id (string, unique)
finished (datetime)
sum (float)

t2
alias_id (string)
sum (float)

таблицы содержат платежи, около 800 тыс. Записей каждая.t1 содержит каждый платеж только один раз, в то время как t2 может иметь несколько записей с одинаковым alias_id - для некоторых платежей может быть несколько транзакций.

Мне нужно сравнить поле суммы в t1 с полями суммы сумм в t2, сгруппированных по псевдониму.

Работа в Excel работает, но болезненно и занимает около 4 часов.Я попытался загрузить таблицы в mysql и выполнить запрос к ним, был удивлен, увидев, что это заняло около 8 часов.

Понятия не имею, почему, возможно, мой запрос плохой?Или, может быть, группировка по времени и сумме делает это?Может действительно использовать общий совет по наилучшему подходу к задаче.

Запрос идет ниже.

SELECT 
    s.alias_id AS id, 
    s.finished AS finished, 
    s.sum AS sum, 
    Sum(b.sum_aggr) AS b_sum 
FROM report.rep1 s 
LEFT  JOIN 
(    SELECT alias_id, SUM(sum) AS sum_aggr    
    FROM   report.rep2
    GROUP  BY 1    
) b 
ON b.alias_id = s.alias_id 
GROUP BY 1, 2, 3;

Таблицы DDL:

first:

CREATE TABLE `rep1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `corp_client_id` longtext,
  `agr_name` longtext,
  `client_id` longtext,
  `order_id` longtext,
  `alias_id` longtext,
  `due` longtext,
  `finished` longtext,
  `sum` double NOT NULL,
  `currency` longtext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=720886 DEFAULT CHARSET=utf8

секунда:

CREATE TABLE `rep2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `client_id` longtext,
  `contract` longtext,
  `contract_start_dt` longtext,
  `contract_end_dt` longtext,
  `country` longtext,
  `provider` longtext,
  `date` longtext,
  `alias_id` longtext,
  `transaction_id` longtext,
  `payment_transaction` longtext,
  `transaction_type` longtext,
  `sum` double NOT NULL,
  `transaction_type_name` longtext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=655351 DEFAULT CHARSET=utf8

1 Ответ

0 голосов
/ 02 октября 2018

Если вы хотите сравнить, что суммы совпадают, вы можете просто сделать left join между таблицами на alias_id.Теперь просто вычислите SUM во второй таблице, и затем вы сможете сравнить их.

Попробуйте вместо этого следующее:

SELECT 
    s.alias_id AS id, 
    s.finished AS finished, 
    s.sum AS sum, 
    SUM(b.sum) AS b_sum 
FROM report.rep1 AS s 
LEFT  JOIN report.rep2 AS s2 ON s2.alias_id = s.alias_id 
GROUP BY s.alias_id, s.finished, s.sum 

РЕДАКТИРОВАТЬ: Как отмечено в комментариях OP , что alias_id не индексируется ни в одном изстолы.Поскольку поле alias_id имеет тип longtext;для этого потребуется правильное индексирование, иначе запросы будут медленными, несмотря ни на что.Теперь поля с типом данных longtext не могут быть проиндексированы;поэтому вам нужно сначала преобразовать их в varchar тип данных.

ALTER TABLE `rep1` MODIFY COLUMN `alias_id` VARCHAR(255);
ALTER TABLE `rep2` MODIFY COLUMN `alias_id` VARCHAR(255);

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

ALTER TABLE `rep1` ADD INDEX alias_id (`alias_id`);
ALTER TABLE `rep2` ADD INDEX alias_id (`alias_id`);

Если собирается alias_idЧтобы быть уникальным в таблице rep1, вы можете использовать следующий оператор (вместо первого оператора выше):

ALTER TABLE `rep1` ADD UNIQUE alias_id (`alias_id`);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...