2016-10-19 96 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)") 

希望这将有助于!

相关问题