2015-10-20 73 views
0

有点背景 - 我在Hibernate 3.5(最相关的是没有联合)。我有项目,并且有标签。标签以项目中的集合的形式存储。我试图编辑我们的数据库搜索组件,以便我可以通过字符串搜索项目,该字符串可以是项目的名称,也可以是标记的名称。实际上,我有两个疑问:在没有表扫描的情况下合并Hibernate查询

select a from Item a where a.name = :searchString; 
select a from Item a join a.tags t where t.name = :searchString; 

最明显的对我的方式,我可以将它们结合起来是这样的:

select a from Item a where a.name = :searchString or a.id in (select b.id from Item b join b.tags t where t.name = :searchString); 

这将产生正确的结果 - 但是,它生成的SQL使我们的MySQL数据库对项目执行全表扫描。这两个单独的查询都不会这样做 - 它是添加了导致扫描的“in”子句。对于我来说,执行两个单独的hql选择并在结果集上的Java代码中执行“穷人联合”可能并不理想,因为它需要彻底更改我们的搜索功能。但是,如果没有联盟,我不知道如何结合查询。任何帮助将不胜感激。

+0

已发布的模式和'explain'。在查询 – Drew

+0

前面的“解释”plop解释下面是我提到的最后一个查询的解释计划 - http://i.imgur.com/kKzzOSz.png。 item_rel_tag是存储项目和标签之间关系的表格。它在映射文件中定义为多对多关系。 –

回答

0

难道你不能只使用left outer join tags和OR离开不同的值?像这样

select distinct a 
from Item a left outer join a.tags t 
where t.name = :searchString or a.name=:searchString; 
+0

Hibernate使以下SQL不在此列: 'SELECT DISTINCT item0 _。* FROM fg_item item0_ LEFT OUTER JOIN fg_item_rel_tag tags1_ ON item0_.item_id = tags1_.item_id LEFT OUTER JOIN k_c_tag tag2_ ON tags1_.tag_id = tag2_.tag_id WHERE tag2_.name ='tag1'OR item0_.name ='tag1'ORDER BY item0_.name LIMIT 50;' 当解释时,这会产生一个通过fg_item的ALL扫描(possible_keys看到fg_item.name但不使用它;额外的信息说“使用临时;使用filesort“。)它返回正确的查询,但仍然是表扫描。 –

+0

错误 - 也就是说,它返回正确的结果集。 –

相关问题