Оптимизация без оконной функции для более старой версии MySQL / MariaDB - PullRequest
0 голосов
/ 25 апреля 2020

Кто-нибудь знает, как упростить сценарий ниже без оконной функции?

Моя версия MariaDB не поддерживает эту функцию.

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

select
    OS.time,
    OS.stat,
    PLOS.codeHS,
    PLOS.codePS,
    PLOS.tariff,
    S.Name as segmentName,
    O.Name as localityName,
    case
        when OS.time = '201911'
            then sum(PLOS.amount)
        when OS.time = '201912' and OS.stat='INV'
            then sum(PLOS.amount)
        when OS.time = '201912' and OS.stat='SIM'
            then coalesce(sum(PLOS.amount),0) - subNovember.calc_amt
        when OS.time = '202001' and OS.stat='INV'
            then sum(PLOS.amount)
        when OS.time = '202001' and OS.stat='SIM'
            then coalesce(sum(PLOS.amount),0) - subDecember.calc_amt
        when OS.time = '202002' and OS.stat='INV'
            then sum(PLOS.amount)
        when OS.time = '202002' and OS.stat='SIM'
            then coalesce(sum(PLOS.amount),0) - subJanuary.calc_amt
end amount
from odstat OS
inner join polstat PLOS on OS.id = PLOS.idOdbytStat
JOIN cssegment S ON S.code=OS.segment
JOIN Locality O ON O.code=PLOS.codeLocality
inner join
   (select subNovember_a.stat, subNovember_b.codeHS, subNovember_b.codePS,
subNovember_b.tariff, O.Name, S.Name as segmentName,
           sum(case
                    when subNovember_a.time = '201911' and subNovember_a.stat='SIM'
                    then subNovember_b.amount
                    else 0    
               end) as calc_amt
    from odstat subNovember_a
    inner join polstat subNovember_b on subNovember_b.idOdbytStat = subNovember_a.id
inner join cssegment S ON S.code= subNovember_a.segment
inner join Locality O ON O.code= subNovember_b.codeLocality
    group by subNovember_a.stat, subNovember_b.codeHS,   subNovember_b.codePS, subNovember_b.tariff , S.Name, O.Name
   ) subNovember
on subNovember.stat = OS.stat
and subNovember.codeHS=PLOS.codeHS
and subNovember.codePS=PLOS.codePS
and subNovember.tariff=PLOS.tariff
and subNovember.segmentName=S.Name
and subNovember.Name=O.Name 
inner join
   (select subDecember_a.stat, subDecember_b.codeHS, subDecember_b.codePS, subDecember_b.tariff, O.Name, S.Name as segmentName,
           sum(case
                    when subDecember_a.time = '201912' and subDecember_a.stat='SIM'
                    then subDecember_b.amount
                    else 0    
               end) as calc_amt
    from odstat subDecember_a
    inner join polstat subDecember_b on subDecember_b.idOdbytStat = subDecember_a.id
inner join cssegment S ON S.code= subDecember_a.segment
inner join Locality O ON O.code= subDecember_b.codeLocality
    group by subDecember_a.stat, subDecember_b.codeHS, subDecember_b.codePS, subDecember_b.tariff , S.Name, O.Name
   ) subDecember
on subDecember.stat = OS.stat
and subDecember.codeHS=PLOS.codeHS
and subDecember.codePS=PLOS.codePS
and subDecember.tariff=PLOS.tariff
and subDecember.segmentName=S.Name
and subDecember.Name=O.Name 
inner join
   (select subJanuary_a.stat, subJanuary_b.codeHS, subJanuary_b.codePS, subJanuary_b.tariff, O.Name, S.Name as segmentName,
           sum(case
                    when subJanuary_a.time = '202001' and subJanuary_a.stat='SIM'
                    then subJanuary_b.amount
                    else 0    
               end) as calc_amt
    from odstat subJanuary_a
    inner join polstat subJanuary_b on subJanuary_b.idOdbytStat = subJanuary_a.id
inner join cssegment S ON S.code= subJanuary_a.segment
inner join Locality O ON O.code= subJanuary_b.codeLocality
    group by subJanuary_a.stat, subJanuary_b.codeHS, subJanuary_b.codePS, subJanuary_b.tariff , S.Name, O.Name
   ) subJanuary
on subJanuary.stat = OS.stat
and subJanuary.codeHS=PLOS.codeHS
and subJanuary.codePS=PLOS.codePS
and subJanuary.tariff=PLOS.tariff
and subJanuary.segmentName=S.Name
and subJanuary.Name=O.Name 
group by
OS.time,
OS.stat,
   PLOS.codeHS,
   PLOS.codePS,
PLOS.tariff,
S.Name,
localityName;

На самом деле, в этом запросе больше месяцев ( тот же процесс для марта, апреля и c.) так что это намного дольше, поэтому я предпочитаю найти хорошую функцию, улучшающую этот скрипт.

1 Ответ

0 голосов
/ 07 мая 2020

Я бы начал с объединения производных таблиц в одну таблицу, используя

GROUP BY ..., time

Если это возможно, то все 4+ подзапроса могут быть выполнены за один проход.

Составной индекс на (tariff, codePS, codeHS), вероятно, поможет. Пожалуйста, предоставьте SHOW CREATE TABLE и EXPLAIN SELECT ....

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