Каков наиболее эффективный способ получить несколько столбцов из нескольких таблиц в Oracle? - PullRequest
0 голосов
/ 07 ноября 2018

Я имею дело с миллиардом записей в оракуле, и мне действительно нужна эффективность. Первая таблица notification. Мне нужно получить следующие данные.

src_data_id | match_data_id

Второй стол - person_info. идентификатор совпадает с src_data_id и match_data_id из таблицы notification.

id | name 

Третья таблица - sample_info, в которой self_object_id - это внешний ключ для person_info.

id | self_object_id

Четвертая таблица - sample_dna_gene, где sample_id совпадает с id в sample_id.

sample_id | gene_info

Я пишу программу на Java и хочу инкапсулировать список объектов. Каждый объект содержит имя (из person_info) и gene_info (из gene_info).

Первоначально я делал это в 2 этапа. Я присоединился к уведомлению и person_info, чтобы получить идентификаторы. Затем я присоединился к person_info, sample_info и gene_info, чтобы получить имена и соответствующие им gene_info.

Это было бы хорошо для небольшой базы данных, но имея дело с миллиардом записей, мне нужно беспокоиться о скорости. Я не должен присоединяться к трем таблицам, как я, но использовать простые sqls для каждой таблицы и вместо этого соединять части в Java.

Было легко получить идентификаторы из person_info с отдельными sqls, но у меня возникли проблемы с получением соответствующих им gene_info. Я могу получить sample_info.id с помощью простого sql, используя in (id1, id2, id3 ...). Затем я могу найти gene_info с другим простым sql, используя in (id1, id2, id3 ...).

Я могу получить все эти списки в Java, но как мне их собрать? Я пользуюсь весной и mybatis. Первоначально я мог сделать один большой грязный sql и инкапсулировать все элементы в маппере. Я не уверен, что теперь делать.

edit: грязный sql, который у меня сейчас есть,

select to_char(sdg.gene_info), max(aa.pid), max(aa.sid), max(aa.id_card_no)
  from (select max(pi.person_name),
           max(pi.id) pid,
           si.id sid,
           max(pi.id_card_no),
           max(pi.race)
      from person_info pi
      join sample_info si
        on pi.id = si.self_object_id
     group by si.id) aa
  join sample_dna_gene sdg
    on sdg.sample_id = aa.sid
 group by to_char(sdg.gene_info)
 where aa.pid in ('...')

Это немного сложнее, чем оригинальный вопрос. Мне нужно сначала сгруппировать по идентификатору в sample_id, затем сгруппировать по gene_info в sample_data_gene. Мне пришлось использовать много max (), чтобы сработала group by, и даже тогда я все еще не мог заставить группу gene_info работать должным образом. Я не уверен, насколько неэффективен max () и насколько он замедлит запрос, но вы можете ясно понять причину, по которой я хотел избежать такого грязного SQL сейчас.

1 Ответ

0 голосов
/ 07 ноября 2018

У меня был похожий случай. Это было delt с 4 отдельными читателями по одному для каждой таблицы, и слияние было сделано на стороне Java. К сожалению, предпосылкой для этого была сортировка потоков доходов на стороне базы данных. Вы читаете одну запись из потока один, затем вы читаете записи из потока 2 до тех пор, пока ключ не изменится (так как вы отсортировали по этому ключу, а ключ является общим для всех вкладок), а затем одинаков для последующих потоков. В моем случае это имело смысл, так как первая таблица была очень широкой, а следующие 3 имели много строк для одного ключа в таблице 1. Если в вашем случае нет отношений 1: n (где n большое), я не понимаю, почему такой подход может быть лучше, чем присоединиться.

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