Пытаюсь выяснить, почему выполнение этого SQL-запроса занимает 47 минут

#sql #excel #vba #qsqlquery

#sql #excel #vba #qsqlquery

Вопрос:

Я пытаюсь выполнить SQL-запрос, но для завершения этого запроса требуется вечность. Запрос выполнен в Excel 2003 с помощью VBA.

Размер ТАБЛИЦЫ:

  • TABLE1 = 12600 строк
  • TABLE2 = 361K строка

Вот запрос:

 SELECT DISTINCT 
    y.code AS CODE,
    y.name AS LIBELLE,
    #[...]
    #[...]
    #[...]
    #[...]
    y.IS_BILAN,
    y.INACTIVE,
    (SELECT COUNT(1) 
     FROM TABLE1 d, TABLE2 a 
     WHERE a.record_date_time >= '2018/01/01' 
       AND a.record_date_time < '2019/01/01' 
       AND global_status <> 'C' 
       AND a.id = d.id 
       AND d.type_id = y.code) AS TOTAL_2018
FROM 
    anal_exam y 
ORDER BY 
    code
  

Весь запрос выполняется мгновенно при удалении последней части «SELECT COUNT (1)»

План выполнения, который я вижу в Oracle SQL Developer:

План выполнения

Как я мог бы ускорить этот запрос? Для завершения требуется 47 минут

Комментарии:

1. Похоже, что ваш подзапрос выполняет перекрестное соединение, что очень неэффективно. Вместо этого рассмотрите возможность перемещения некоторых where предложений (особенно a.id = d.id ) в join.

2. Я довольно новичок в SQL, и у меня возникли проблемы с пониманием того, куда я должен переместить a.id = d.id

Ответ №1:

Попробуйте определить свой JOIN следующим образом:

 SELECT DISTINCT 
 y.code AS CODE,
 y.name AS LIBELLE,
 y.IS_BILAN,
 y.INACTIVE,
 COUNT(*) AS TOTAL_2018
FROM anal_exam y 
JOIN TABLE1 d
  ON d.type_id = y.code
  JOIN TABLE2 a 
    ON d.ID = a.ID
WHERE a.record_date_time BETWEEN '2018/01/01' AND '2019/01/01'
  AND global_status <> 'C'
order by code
  

Комментарии:

1. С этим кодом я получаю сообщение об ошибке в редакторе vba — ORA-00937: отсутствует групповая функция с одной группой

Ответ №2:

Я добавил GROUP BY y.code, y.name, y.IS_BILAN, y.inactive в конце, и это работает

  • время выполнения составляет 47 секунд.

Это довольно быстро, но мне интересно, есть ли способ получить строку с count = 0, потому что в этом запросе опущены строки 3k

Ответ №3:

С помощью кода из T McKeown я получаю этот результат :

 CODE1|LIBELLE1|T|T|1530
CODE3|LIBELLE2|T|T|20
CODE5|LIBELLE3|T|T|143
  

Результат, который я ищу, включает строку с count () = 0

 CODE1|LIBELLE1|T|T|1530
CODE2|LIBELLE2|T|F|0
CODE3|LIBELLE2|T|F|20
CODE4|LIBELLE4|T|T|0
CODE5|LIBELLE3|F|T|143
  

Как я могу этого добиться?