Слишком высокая стоимость выбора базы данных - PullRequest
1 голос
/ 26 февраля 2020

Я хочу использовать двойной INNER SELECT в моей базе данных. Если я использую его через HIBERNATE и сущности в моем приложении java, отладчик получит ошибку G C.

  SELECT * FROM campaign WHERE id_campaign  IN 
    (SELECT id_campaign FROM event WHERE id_event IN 
     (SELECT id_event FROM dataset_event WHERE id_dataset=xxx)) limit 100;

Есть ли лучший способ без ошибки G C? Может быть, другой выбор? Заполняет ли Hibernate объекты-события второго внутреннего выбора? Это не обязательно, я думаю ..

К вашему сведению:

enter image description here

Ошибка в консоли:

26-Feb-2020 09:36:36.575 SCHWERWIEGEND [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run Unexpected death of background thread [ContainerBackgroundProcessor[StandardEngine[Catalina]]]
    java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]" java.lang.OutOfMemoryError: GC overhead limit exceeded

Hibernate версия 5.3.3. Финал

Ответы [ 2 ]

0 голосов
/ 26 февраля 2020

Это, вероятно, делает то, что вы хотите:

SELECT c.*
FROM campaign c JOIN
     event e
     ON c.id_campaign = e.id_campaign JOIN
     dataset_event de
     ON de.id_event = e.id_event
WHERE de.id_dataset = xxx
LIMIT 100;

Для производительности вам нужны индексы:

  • dataset_event(id_dataset, id_event)
  • event(id_event, id_campaign)
  • campaign(id_campaign)

Возможно, у вас уже есть некоторые или все из них.

Вышеприведенное может вернуть дубликаты. Очевидно, вы можете использовать select distinct или distinct on, но это может быть довольно дорого. Вместо этого, exists может быть лучшим решением:

SELECT c.*
FROM campaign c 
WHERE EXISTS (SELECT 1
              FROM event e JOIN
                   dataset_event de
                   ON de.id_event = e.id_event
              WHERE c.id_campaign = e.id_campaign AND
                    de.id_dataset = xxx
             )
LIMIT 100;

Для этого вам нужны индексы:

  • event(id_campaign, id_event)
  • dataset_event(id_event, id_dataset)
0 голосов
/ 26 февраля 2020

Я думаю, что использовать этот запрос лучше, чем вышеупомянутый запрос:

  SELECT * 
  FROM campaign  AS c
  OUTER APPLY(
     SELECT id_campaign FROM event AS e WHERE e.id_campaign = c.id_campaign
             ) AS p
  OUTER APPLY(
     SELECT id_event FROM dataset_event AS d WHERE id_dataset=xxx AND d.id_event = 
     p.id_event
             ) AS o 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...