2016-10-19 6 views
0

私は、OtherTableに少なくとも1回出現するユーザーのリストを取得しようとしています。以下はGrailsを使用した非常に非効率なHQLクエリです。一般に、クエリで実行されるユーザーは最大でも数百人に過ぎませんが、OtherTableのユーザーは100万人になる可能性があります。SQL - 他のテーブルに少なくとも1回表示される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上で50,000行のOtherTableでH2を実行するには1秒以上かかりましたが、最終的なハードウェアはより良いハードウェア上でMS SQLになります。 – Anonymous1

+0

SQL Serverのインデックスを使用してクエリを高速化できます。 –

答えて

2

上記は、ドメインの適切なマッピングを必要とする両

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

基準APIを使用して、この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 

クラス。場合によっては、OtherTableUserにマッピングされていません。試してみてください。

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

ここでは完全なテーブルスキャンを完全に避けていることに気がつくかもしれません。サブクエリを使用する、あなたが投稿したクエリとは異なり、単一のクエリです。 idで両方のエンティティ/テーブルを結合する方が効率的です。idという列がインデックスされていると仮定します。

+0

これは、より良いaproachですが、他の人が与えていないin文は非効率です – 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)") 

はそれに役立つことを願っています!

関連する問題