проблема запроса гибернации, так близко и в тупик - PullRequest
0 голосов
/ 11 июня 2009

Схема: (Psuedocode)

У меня есть компонент, который называется BaseEntity ...

@Entity
class BaseEntity {
   @OneToMany @CascadeType.ALL
   List [Property] properties;
   //the use angled braces ommited for the stackoverflow editor to show up properly
}

Собственность - это еще один боб ...

@Entity
class Property {
   @ManyToOne
   Category category;
   @OneToOne
   Value value;
}

Значение на самом деле является абстрактным классом с Inheritence.SingleTable и подклассами, такими как NumericValue и DateValue и т. Д., А также (в абстрактном классе Value) типом @ManyToOne BaseType.

Цель:

Я пытаюсь написать запрос, который выбирает объекты BaseEntity, у которых есть свойство, которое имеет категорию с определенным именем, и выбираю несколько из них, получая объекты, которые имеют любое из заданных свойств, и получая значение NULL в полях, которые не не существует.

Попытка:

select entity.id as id, foo as foo, bar as bar 
from BaseEntity entity, Value foo, Value bar 
where foo in (select p.value from Property p where p in elements(entity.properties) and p.category.name = 'FOO') 
or bar in (select p.value from Property p where p in elements(entity.properties) and p.category.name = 'BAR')

Этот запрос выполняется. В настоящее время в базе данных есть один BaseEntity, который совпадает, и я получаю его много раз с правильным результатом для foo, который он содержит, но это одно и то же право снова и снова со многими значениями в поле bar.

Кроме того, для запуска требуется, как ПЯТЬ МИНУТ, и он задерживает всех остальных, использующих базу данных.

Идеи:

Конечно, я подумал о том, чтобы использовать какое-то отличительное, но это не относится к тому времени, которое требуется для бега, и я просто не совсем понимаю, что происходит.

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


Я бы прокомментировал, но этот код слишком длинный для поля для комментариев ... Я выполнил запрос, этот не такой длинный, что он зависает, но больше присоединяется, и он не зависает, а завершается ... выполнение этого запроса занимает МИНУТ.

Я запустил запрос из своего кода и включил show_sql в свойствах спящего режима.

</p> <p>select baseentity0_.entityId as col_0_0_, property2_.value_valueId as col_1_0_, property4_.value_valueId as col_2_0_, property6_.value_valueId as col_3_0_, property8_.value_valueId as col_4_0_, property10_.value_valueId as col_5_0_, value11_.valueId as valueId9_0_, value12_.valueId as valueId9_1_, value13_.valueId as valueId9_2_, value14_.valueId as valueId9_3_, value15_.valueId as valueId9_4_, value11_.type_typeId as type6_9_0_, value11_.numericalValue as numerica3_9_0_, value11_.textValue as textValue9_0_, value11_.dateValue as dateValue9_0_, value11_.value_entityId as value7_9_0_, value11_.DTYPE as DTYPE9_0_, value12_.type_typeId as type6_9_1_, value12_.numericalValue as numerica3_9_1_, value12_.textValue as textValue9_1_, value12_.dateValue as dateValue9_1_, value12_.value_entityId as value7_9_1_, value12_.DTYPE as DTYPE9_1_, value13_.type_typeId as type6_9_2_, value13_.numericalValue as numerica3_9_2_, value13_.textValue as textValue9_2_, value13_.dateValue as dateValue9_2_, value13_.value_entityId as value7_9_2_, value13_.DTYPE as DTYPE9_2_, value14_.type_typeId as type6_9_3_, value14_.numericalValue as numerica3_9_3_, value14_.textValue as textValue9_3_, value14_.dateValue as dateValue9_3_, value14_.value_entityId as value7_9_3_, value14_.DTYPE as DTYPE9_3_, value15_.type_typeId as type6_9_4_, value15_.numericalValue as numerica3_9_4_, value15_.textValue as textValue9_4_, value15_.dateValue as dateValue9_4_, value15_.value_entityId as value7_9_4_, value15_.DTYPE as DTYPE9_4_ from BaseEntity baseentity0_ inner join BaseEntity_Property properties1_ on baseentity0_.entityId=properties1_.BaseEntity_entityId inner join Property property2_ on properties1_.properties_propertyId=property2_.propertyId inner join Value value11_ on property2_.value_valueId=value11_.valueId inner join BaseEntity_Property properties3_ on baseentity0_.entityId=properties3_.BaseEntity_entityId inner join Property property4_ on properties3_.properties_propertyId=property4_.propertyId inner join Value value12_ on property4_.value_valueId=value12_.valueId inner join BaseEntity_Property properties5_ on baseentity0_.entityId=properties5_.BaseEntity_entityId inner join Property property6_ on properties5_.properties_propertyId=property6_.propertyId inner join Value value13_ on property6_.value_valueId=value13_.valueId inner join BaseEntity_Property properties7_ on baseentity0_.entityId=properties7_.BaseEntity_entityId inner join Property property8_ on properties7_.properties_propertyId=property8_.propertyId inner join Value value14_ on property8_.value_valueId=value14_.valueId inner join BaseEntity_Property properties9_ on baseentity0_.entityId=properties9_.BaseEntity_entityId inner join Property property10_ on properties9_.properties_propertyId=property10_.propertyId inner join Value value15_ on property10_.value_valueId=value15_.valueId, Category category16_, Category category17_, Category category18_, Category category19_, Category category20_ where property2_.category_categoryId=category16_.categoryId and property4_.category_categoryId=category17_.categoryId and property6_.category_categoryId=category18_.categoryId and property8_.category_categoryId=category19_.categoryId and property10_.category_categoryId=category20_.categoryId and category16_.name='Sample Name / Strain' and category17_.name='Item #' and category18_.name='THC_Result' and category19_.name='CBD_Result' and category20_.name='CBN_Result'</p> <p>


Что ж, я хотел продолжить и сказать, что то, что чудесно сработало с двумя операторами соединения, нелепо с пятью.

select entity.id as entityId, strain.value as name, item.value as itemNum, thc.value as THC, cbd.value as CBD, cbn.value as CBN</p> <p>from BaseEntity as entity join entity.properties as strain join entity.properties as item join entity.properties as thc join entity.properties as cbd join entity.properties as cbn where strain.category.name = 'Sample Name / Strain' and item.category.name = 'Item #' and thc.category.name = 'THC_Result' and cbd.category.name = 'CBD_Result' and cbn.category.name = 'CBN_Result'</p> <p> Какие-нибудь предложения относительно лучшего способа сделать это будет быстрее с моей глупой схемой?

Ответы [ 4 ]

1 голос
/ 11 июня 2009

Проблема с производительностью выглядит так, как будто она у вас выбрана.

А как насчет того, чтобы немного разбить его?

select entity from BaseEntity as entity join entity.properties as property where
property.category.name in ( 'FOO','BAR' )

Это даст вам список базовых сущностей со свойством FOO или BAR, тогда, если вы хотите ограничить коллекции baseEntity.properties, используйте фильтр или запрос для получения свойств.

from properity where  property.category.name in ( 'FOO', 'BAR' )
and property.baseEntity.priKey = :priKey 
0 голосов
/ 12 июня 2009

Этот запрос выглядит разумным для меня. Итак, вопрос:

Какой SQL-код генерирует в спящем режиме для этого HQL?

Какой план запроса создает база данных для этого SQL?

В Sybase или MS SQL Server: «включить showplan». В Oracle используйте SQLDeveloper / Toad и выберите план / Скорая помощь.

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

0 голосов
/ 11 июня 2009

Это был абсолютно ответ cclark, который подтолкнул меня в этом направлении, и мой хороший друг тоже помог ...

select entity.id as entityId, entity.type as entityType, p1.value as Vendor, p2.value as Weight 
from BaseEntity as entity 
join entity.properties as p1 
join entity.properties as p2 
where p1.category.name = 'Vendor' and p2.category.name = 'Total Weight'

делает именно то, что мне нужно. СПАСИБО ВАМ ОБЩЕСТВА!

0 голосов
/ 11 июня 2009

Вы переопределяете типы выборки по умолчанию для ассоциаций? Обычно это приводит к проблеме. Можете ли вы опубликовать запрос, который генерирует Hibernate?

...