2015-10-20 74 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

錯誤 - 也就是說,它返回正確的結果集。 –

相關問題