SQL-选择在其他表中至少出现一次的ID

SQL-选择在其他表中至少出现一次的ID,sql,grails,hql,gorm,Sql,Grails,Hql,Gorm,我正在尝试获取在OtherTable中至少出现一次的用户列表。下面是我使用Grails进行的效率非常低的HQL查询。一般来说,查询中最多只能运行几百个用户,但在OtherTable中可能会有一百万个对这些用户的引用 List<User> users = User.executeQuery("select user " + "from User as user where user.id = any(" +

我正在尝试获取在OtherTable中至少出现一次的用户列表。下面是我使用Grails进行的效率非常低的HQL查询。一般来说,查询中最多只能运行几百个用户,但在OtherTable中可能会有一百万个对这些用户的引用

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

如何使此查询更高效?

此SQL可能更高效

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。试试这个

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

您可能已经注意到,我们在这里完全避免了全表扫描;它是一个单一的查询-不像你发布的那个,它使用子查询。连接两个id为的实体/表应该更有效-假设id列已被索引。

此SQL可能更有效

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。试试这个

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

您可能已经注意到,我们在这里完全避免了全表扫描;它是一个单一的查询-不像你发布的那个,它使用子查询。连接两个id为的实体/表应该更有效-假设id列已被索引。

请尝试以下查询:

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

希望这会有帮助

尝试以下查询:

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

希望这会有帮助

如果这个查询有效的话,那么它可能是相当有效的。也许当时是我的测试硬件?在H2上用50000行OtherTable在我的电脑上运行花费了一秒多的时间,但最终的硬件将是更好的硬件上的MS SQL。您可以在SQL Server中使用索引来加速查询。@GordonLinoff,您可能没有注意到,但OtherTable上有一个完整的表扫描。如果此查询有效,那么它可能相当有效。也许当时是我的测试硬件?在H2上用50000行OtherTable在我的电脑上运行需要一秒钟,但最终的硬件将是更好的硬件上的MS SQL。您可以在SQL Server中使用索引来加快查询速度。@GordonLinoff,您可能没有注意到,但OtherTable上有一个完整的表扫描。这是更好的方法,其他人给出的in语句是非有效的,我只需要返回不同的用户-建议的查询返回所有匹配的OtherTable。不幸的是,无论是否使用distinct关键字,此查询都要慢得多。@Anonymous1,是的,它可能包含重复项;我做了相应的修改。这是一个更好的方法,其他人给出的in语句是无效的。我只需要返回不同的用户-建议的查询返回所有匹配的OtherTable。不幸的是,无论是否使用distinct关键字,此查询都要慢得多。@Anonymous1,是的,它可能包含重复项;我做了相应的修改。