Запрос выполняется бесконечно и не хватает памяти - MySQL 8.0.16 AWS RDS - PullRequest
0 голосов
/ 11 марта 2020

Кто-нибудь может мне помочь с этим запросом в MySQL 8.0.16? Этот запрос бесконечно выполняется на AWS RDS и выходит из памяти, и я полагаю, что проблема связана с операторами UNION ALL и GROUP BY.


SELECT 
       SUM(`CONV`.`ELEGIVEL`) AS `ELEGIVEL`,
       SUM(`CONV`.`ADESAO`) AS `ADESAO`,
       `CONV`.`ano` AS `ano`,
       `CONV`.`mes` AS `mes`,
       `CONV`.`TIPO` AS `TIPO`
   FROM
       (


SELECT 
           SUM(`v`.`QuantidadeItem`) AS `ELEGIVEL`,
               NULL AS `ADESAO`,
               `v`.`ano` AS `ano`,
               `v`.`mes` AS `mes`,
               'BENCH' AS `TIPO`
       FROM
           `V_VENDAS_ELEGIVEIS` `v`
       WHERE
           ((`v`.`nome_emp` LIKE '%ESB%')
               AND (`v`.`data_lancamento` BETWEEN DATE_FORMAT((NOW() - INTERVAL 12 MONTH), '%Y-%m-01') AND LAST_DAY((CURDATE() - INTERVAL 1 MONTH))))
       GROUP BY `v`.`ano` , `v`.`mes` UNION ALL SELECT 
           NULL AS `ELEGIVEL`,
               COUNT(0) AS `ADESAO`,
               `V_SEGUROS_ADESAO`.`Ano` AS `ano`,
               `V_SEGUROS_ADESAO`.`Mes` AS `mes`,
               'BENCH' AS `TIPO`
       FROM
           `V_SEGUROS_ADESAO`
       WHERE
           ((`V_SEGUROS_ADESAO`.`nome_emp` LIKE '%ESB%')
               AND (`V_SEGUROS_ADESAO`.`dataemissao` BETWEEN DATE_FORMAT((NOW() - INTERVAL 12 MONTH), '%Y-%m-01') AND LAST_DAY((CURDATE() - INTERVAL 1 MONTH))))
       GROUP BY `V_SEGUROS_ADESAO`.`Ano` , `V_SEGUROS_ADESAO`.`Mes` UNION ALL SELECT 
           SUM(`v`.`QuantidadeItem`) AS `ELEGIVEL`,
               NULL AS `ADESAO`,
               `v`.`ano` AS `ano`,
               `v`.`mes` AS `mes`,
               'BRAND' AS `TIPO`

       FROM
           `V_VENDAS_ELEGIVEIS` `v`
       WHERE
           (`v`.`data_lancamento` BETWEEN DATE_FORMAT((NOW() - INTERVAL 12 MONTH), '%Y-%m-01') AND LAST_DAY((CURDATE() - INTERVAL 1 MONTH)))
       GROUP BY `v`.`ano` , `v`.`mes` UNION ALL SELECT 
           NULL AS `ELEGIVEL`,
               COUNT(0) AS `ADESAO`,
               `V_SEGUROS_ADESAO`.`Ano` AS `ano`,
               `V_SEGUROS_ADESAO`.`Mes` AS `mes`,
               'BRAND' AS `TIPO`
       FROM
           `V_SEGUROS_ADESAO`
       WHERE
           (`V_SEGUROS_ADESAO`.`dataemissao` BETWEEN DATE_FORMAT((NOW() - INTERVAL 12 MONTH), '%Y-%m-01') AND LAST_DAY((CURDATE() - INTERVAL 1 MONTH)))
       GROUP BY `V_SEGUROS_ADESAO`.`Ano` , `V_SEGUROS_ADESAO`.`Mes`

) `CONV`

GROUP BY `CONV`.`ano` , `CONV`.`mes`, `CONV`.`TIPO`

Если я разделю запрос выше на один запрос за раз, как код ниже, результат довольно быстро.

SELECT 
       SUM(`BENCH`.`ELEGIVEL`) AS `ELEGIVEL`,
       SUM(`BENCH`.`ADESAO`) AS `ADESAO`,
       `BENCH`.`ano` AS `ano`,
       `BENCH`.`mes` AS `mes`,
       'BENCHMARK' AS `TIPO`
   FROM
       (SELECT 
           SUM(`v`.`QuantidadeItem`) AS `ELEGIVEL`,
               NULL AS `ADESAO`,
               `v`.`ano` AS `ano`,
               `v`.`mes` AS `mes`
       FROM
           `V_VENDAS_ELEGIVEIS` `v`
       WHERE
           ((`v`.`nome_emp` LIKE '%ESB%')
               AND (`v`.`data_lancamento` BETWEEN DATE_FORMAT((NOW() - INTERVAL 12 MONTH), '%Y-%m-01') AND LAST_DAY((CURDATE() - INTERVAL 1 MONTH))))
       GROUP BY `v`.`ano` , `v`.`mes` UNION ALL SELECT 
           NULL AS `ELEGIVEL`,
               COUNT(0) AS `ADESAO`,
               `V_SEGUROS_ADESAO`.`Ano` AS `ano`,
               `V_SEGUROS_ADESAO`.`Mes` AS `mes`
       FROM
           `V_SEGUROS_ADESAO`
       WHERE
           ((`V_SEGUROS_ADESAO`.`nome_emp` LIKE '%ESB%')
               AND (`V_SEGUROS_ADESAO`.`dataemissao` BETWEEN DATE_FORMAT((NOW() - INTERVAL 12 MONTH), '%Y-%m-01') AND LAST_DAY((CURDATE() - INTERVAL 1 MONTH))))
       GROUP BY `V_SEGUROS_ADESAO`.`Ano` , `V_SEGUROS_ADESAO`.`Mes`) `BENCH`
   GROUP BY `BENCH`.`ano` , `BENCH`.`mes`

Сервер основан на AWS RDS. Я не изменил ни одну группу параметров, это параметр default.mysql8.0.

Это экземпляр db.t3.medium и он имеет 4 ГБ ОЗУ

1 Ответ

0 голосов
/ 12 марта 2020

Вложенные операторы SELECT с группировкой на каждом уровне слишком сложны и неэффективны. Я настоятельно рекомендую перестроить вашу логику c в хранимую процедуру, где вы можете использовать временные таблицы и комбинацию более простых команд для сбора данных по одному шагу за раз.

...