2016-10-19 97 views
0

我試圖獲取在OtherTable中至少出現一次的用戶列表。以下是使用Grails的非常低效的HQL查詢。通常,最多隻有幾百個用戶在查詢中運行,但可能會有一百萬個用戶在OtherTable中引用這些用戶。SQL - 選擇在其他表中至少出現一次的ID

List<User> users = User.executeQuery("select user " + 
        "from User as user where user.id = any(" + 
        "select otherTable.user.id from OtherTable as otherTable)") 

如何讓此查詢更高效?

+0

如果此查詢有效,那麼它可能非常有效。 –

+0

也許是我的測試硬件呢?在我的PC上花費了超過一秒的時間在H2上運行50,000行OtherTable,但最終的硬件在更好的硬件上是MS SQL。 – Anonymous1

+0

您可以使用SQL Server中的索引來加速查詢。 –

回答

2

這個SQL可能更爲effcient,

select distinct u.id from user as u 
inner join other_table ot 
on u.id = ot.id 

這裏是一個HQL,

select distinct user 
from User as user 
inner join user.otherTable as ot 

使用標準的API

User.createCriteria().listDistinct { 
    createAlias("otherTable","ot") 
    eq('id','ot.id') 
} 

上述兩種需要您的域的正確映射類。如果沒有,OtherTable,映射在User。試試這個,

select distinct user from User user, OtherTable ot 
where user.id = ot.user_id 

您可能已經注意到我們在這裏完全避免了全表掃描;這是一個單一的查詢 - 與您發佈的查詢不同,後者使用子查詢。加入id這兩個實體/表應該更有效率 - 假設id列被編入索引。

+0

這是更好的方法,其他人給出的聲明無效 – quindimildev

+0

我只需要返回不同的用戶 - 查詢建議返回所有匹配的OtherTable。不幸的是,這個查詢在使用和不使用distinct關鍵字時要慢得多。 – Anonymous1

+0

@ Anonymous1,是的,它可能包含重複;我相應地修改了。 –

0

嘗試以下查詢:

List<User> users = User.executeQuery("select user " + 
        "from User as user where" + 
        "user.id in (select distinct otherTable.user.id from OtherTable as otherTable)") 

希望這將有助於!

相關問題