@aminodovborisov

Как ускорить запрос SELECT с LISTAGG?

Здравствуйте.
Есть две таблицы, humans и connects. Вот такие:
-- humans

id              name
1001            Алексеев Алексей Алексеевич
1002            Борисов Борис Борисович
1003            Васильев Василий Васильевич
...


-- connects

id      humanid     type        conn
2001    1001        phone       123456
2002    1001        email       alekseev@aa.ru
2003    1001        email       alekseev@gmail.com
2004    1001        email       alekseev@yandex.ru
2005    1002        phone       234532
2006    1002        phone       232323
2007    1002        phone       212121
2008    1003        email       vasiliev@vv.ru
2009    1003        phone       345678
2010    1003        phone       313131


И я хочу получить вот такой результат:
id      name                           phone                    
1001    Алексеев Алексей Алексеевич    123456                  
1002    Борисов Борис Борисович        212121,232323,234532   
1003    Васильев Василий Васильевич    313131,345678


А потом такой же результат с емейлами.
Запрос у меня вот такой:

with qconnect as
(
    select 
        humanid, 
        listagg(conn, ',') within group(order by conn) as phone
    from connects
    where 
        type = 'phone'
    group by humanid
)
select
    h.id,
    h.name,
    c.phone
from
    humans h,
    qconnect c
where h.id = c.humanid;


Проблема в том, что таблицы на самом деле очень большие. И, самое главное, если записей с телефонами там десятки тысяч, то записей с емейлами — десятки миллионов. Поэтому неудивительно, что запрос с телефонами обрабатывается 5-6 секунд, то запрос с емейлами — более пяти минут.

Собственно вопрос.
Можно ли ускорить этот запрос? Я вот почему-то думаю, что корень зла таится в listagg, как-то не так он записан. Как-то можно оттуда достучаться к h.id. Но как?
Спасибо!
  • Вопрос задан
  • 121 просмотр
Пригласить эксперта
Ответы на вопрос 1
idShura
@idShura
Попробуй вот так, и желательно увидеть план запроса
select h.id, 
       h.name, 
       listagg(c.conn, ',') within group(order by c.conn) as phone 
  from humans h
       left join connects c on c.humanid = h.id
 where c.type = 'phone'
 group by h.id, 
          h.name
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы