Улучшить производительность запросов и удобство обслуживания - PullRequest
0 голосов
/ 03 марта 2020

У меня есть запрос, подобный следующему:

select Table1.column1 AS CODE, COUNT(DINSTINCT(Table2.column1 || '|' || Table2.column2)) AS COUNT
FROM   Table2
INNER JOIN Table3 ON Table3.referenceColumn = Table2.referenceColumn
INNER JOIN Table1 ON Table1.referenceColumn = Table2.referenceColumn
WHERE
....
AND Table1.column1 <> ''

Результат запроса будет примерно таким, в основном это CODE и соответствующий COUNT, например:

CODE    COUNT
ref002   3
ref003   1

После этого первого запроса у меня есть foreach, который будет повторять результат запроса выше. Внутри foreach для каждого результата запроса, приведенного выше, я хочу получить некоторую информацию, которая доступна в Таблице3, в основном, мне нужны все значения в Table3.column1 для каждого КОДА (Table1.Column1). Поэтому внутри foreach у меня есть другой запрос, чтобы получить столбец Table3.column для каждого повторного результата:

select Table3.column1
FROM   Table3
INNER JOIN Table3 ON Table3.referenceColumn = Table2.referenceColumn
INNER JOIN Table1 ON Table1.referenceColumn = Table2.referenceColumn
WHERE .... 
AND Table1.column1 = (equal to a parameter (Table1.column1) that is available in each foreach iteration)

И вот так, я могу получить все значения Table3.column1 для каждого Table1.column1 (для каждый код) первого запроса.

Сомнение

Оба запроса практически одинаковы. Единственное различие между запросом перед foreach и запросом внутри foreach заключается в части SELECT и в WHERE, в основном там, где просто есть дополнительное условие. Таким образом, это не очень хорошо с точки зрения производительности, а обслуживаемость имеет 2 запроса, потому что оба запроса почти одинаковы. Таким образом, должна быть возможность получить всю необходимую информацию в первом запросе вместо того, чтобы иметь второй запрос внутри foreach.

Знаете ли вы, что необходимо изменить в первом запросе, кроме возврата CODE и COUNT, также возвращают все значения в Table3.column1 для каждого CODE? Так что же можно удалить запрос внутри foreach и получить все, что нужно, только одним запросом (1-й запрос)? Необходимый вывод для первого запроса должен выглядеть примерно так:

CODE     COUNT     IDNUMBERS
ref002    3         ab00, cd00
ref003    1         ef00

1 Ответ

3 голосов
/ 03 марта 2020

Ваша стратегия генерирует один запрос на код, плюс один для исходного запроса, так что это действительно неэффективно.

Один простой вариант - использовать функцию агрегирования строк в исходном запросе для создания дополнительного столбца.

В Oracle вы можете использовать listagg() для этого:

select 
    t1.column1 as code, 
    count(distinct t2.column1 || '|' || t2.column2) as cnt,
    listagg(t3.column1) idnumbers
from   table2 t2
inner join table3 t3 on t3.referencecolumn = t2.referencecolumn
inner join table1 t1 on t1.referencecolumn = t1.referencecolumn
where ...
group by t1.column1

listagg() имеет различные опции для форматирования, дублирования управления и сортировки - вы можете найти детали в документации .

...