Запрос Hibernate на родительский класс создает неэффективный запрос объединения - PullRequest
0 голосов
/ 27 ноября 2018

Я использую Spring boot и Hibernate, и у меня следующая структура данных.

@Entity
public class Template {

  @Id
  private Integer id;

  @OneToMany(mappedBy = "template", orphanRemoval = true, fetch = FetchType.EAGER,cascade = CascadeType.ALL)
  @BatchSize(size = 30)
  private Collection<TemplateContent> contents;
}

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class TemplateContent {

  @Id
  private String contentType;

  @Id
  @ManyToOne(fetch = FetchType.EAGER, optional = false)
  @JoinColumn(name = "template_id", nullable = false)
  private Template template;
}

@Entity
public class SomeContent extends TemplateContent {

   private String someValue;
}

@Entity
public class SomeOtherContent extends TemplateContent {

   private String someOtherValue;
}

@Repository
public interface TemplateRepository extends JpaRepository<Template, Integer> {
  Page<Template> findByIdIn(Collection<Integer> ids, Pageable pageable);
}

Когда я вызываю метод findByIdIn, он генерирует следующий запрос:

SELECT ...
FROM   (SELECT content_type, 
               template_id, 
               some_value, 
               NULL AS some_other_value
        FROM   someContent
        UNION 
    SELECT content_type, 
               template_id, 
               some_other_value, 
               NULL AS some_value
        FROM   someOtherContent) contents0_ 
WHERE  contents0_.template_id IN ( ?, ?, ? ) 

, который неэффективен,потому что MySQL не может использовать индексы над производными таблицами.Есть ли способ сгенерировать более эффективный запрос.

//this would be the desired query
SELECT ...
FROM   (SELECT content_type, 
               template_id, 
               some_value, 
               NULL AS some_other_value
        FROM   someContent
        WHERE template_id IN ( ?, ?, ? )
        UNION 
    SELECT content_type, 
               template_id, 
               some_other_value, 
               NULL AS some_value
        FROM   someOtherContent
        WHERE template_id IN ( ?, ?, ? )) contents_0_ ....

Я также пытался использовать разные стратегии наследования, но, похоже, у всех них есть похожий недостаток.

1 Ответ

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

Если вы хотите добиться максимальной производительности в полиморфном запросе, лучше всего использовать strategy = InheritanceType.SINGLE_TABLE, возможно, вы будете платить за производительность пустыми столбцами, но это зависит от того, какой аспект для вас важнее, также потому, что strategy = InheritanceType.JOINED имеет то же самоепроблемы TABLE_PER_CLASS

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