Mysql оптимизационный запрос на 2 таблицы

0

Пусть db1 и db2 db1.table1

annee   code    code2   var1    ....
1991    11    12    779
1991    11    14    105
1991    11    15    10
1991    12    11    466
1991    12    14    296
1991    12    15    270
1991    14    11    15
1991    14    12    510
1991    14    15    6
1991    15    11    193
1991    15    12    455
1991    15    14    4   
....
1992    11    12    779
1992    11    14    105
1992    11    15    10
1992    12    11    466
1992    12    14    296
1992    12    15    270
1992    14    11    15
1992    14    12    510
1992    14    15    6
1992    15    11    193
1992    15    12    455
1992    15    14    4   
....

db2.table2

var1    code    ...
test  11
test  12
test  14
test2 11
test2 14
test2 15
...

Мне нужно оптимизировать следующий запрос (потому что db1.table1 содержит 8 000 000 строк):

select annee,sum(var1) from db1.table1 as M where 
M.code in 
(select t1.code from db2.table2 as t1 cross join db2.table2 as t2 where t1.var1='Test2' and t2.var1='Test2' and t1.code <> t2.code) 
and M.code2 in 
(select t2.code from db2.table2 as t1 cross join db2.table2 as t2 where t1.var1='Test2' and t2.var1='Test2' and t1.code <> t2.code) 
group by annee order by annee desc

db1.table1 и db2.table2 индексируются и сортируются. Любые советы будут высоко ценится! Спасибо

Теги:
optimization
select

3 ответа

2

В качестве варианта вы можете попробовать следующее

select m.annee,sum(m.var1)
from db1.table1 m
join
  (
    select t1.code code1,t2.code code2
    from db2.table2 t1
    join db2.table2 t2 on t1.var1='Test2' and t2.var1=t1.var1 and t1.code<t2.code
  ) c
on (m.code=c.code1 and m.code2=c.code2) or (m.code=c.code2 and m.code2=c.code1)
group by m.annee
order by m.annee desc

Я использовал JOIN вместо CROSS JOIN и JOIN вместо двух IN.

И если это вам подходит, вы можете попробовать оптимизировать запрос

select m.annee,sum(m.var1)
from db2.table2 t1
join db2.table2 t2 on t1.var1='Test2' and t2.var1=t1.var1 and t1.code<t2.code
join db1.table1 m on (m.code=t1.code and m.code2=t2.code) or (m.code=t2.code and m.code2=t1.code)
group by m.annee
order by m.annee desc

Первый JOIN возвращает все комбинации для test2. Существуют (11,12) и (11,14)

db2.table2 t1
join db2.table2 t2 on t1.var1='Test2' and t2.var1=t1.var1 and t1.code<t2.code

И вторая JOIN проверяет строки из table1 на эти комбинации

join db1.table1 m on (m.code=t1.code and m.code2=t2.code) or (m.code=t2.code and m.code2=t1.code)

Попробуйте также проверить следующий вариант

select m.annee,sum(m.var1)
from db2.table2 t1
join db2.table2 t2 on t1.var1='Test2' and t2.var1=t1.var1 and t1.code<>t2.code
join db1.table1 m on m.code=t1.code and m.code2=t2.code
group by m.annee
order by m.annee desc

Если последний вариант возвращает правильный результат, вы можете попытаться добавить индекс для (code,code2) в table1

CREATE INDEX idx_table1_code_code2 ON db1.table1 (code,code2)
  • 0
    Я обдумывал это. И я не думаю, что это даст результаты, которые требует OP, поскольку их исходный код ищет соответствующий код из t1 и t2, но не обязательно из той же строки
  • 0
    @ Kickstart - Да, я снова посмотрел запрос и думаю, что ты прав.
Показать ещё 14 комментариев
1

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

    select annee,sum(var1) 
        from db1.table1 as M where 
            exists( select var1 from db2.table2 t2 
                        where t2.var1='Test2' 
                        group by t2.var1 
                        having sum(t2.code = M.code) >= 1 
                            and sum(t2.code = M.code2) >= 1 
                            and (M.code != M.code2 or sum(t2.code != M.code) >= 1))

        group by annee 
        order by annee desc
0
table2: INDEX(var1, code)
table1: INDEX(code, code2, annee)

Измените IN ( SELECT... ) в JOIN ( SELECT... ) ON...; первый плохо оптимизирован.

Если вы используете MySQL 5.6 или новее, то подзапросы могут быть достаточно оптимизированы. Если вы используете более старую версию, создайте TEMPORARY TABLE с дублированным подзапросом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню