3

この(簡単にするために変更された)クエリは、より大きなクエリの一部であり、日付に他の選択と結合されます。しかし、私はこのセクションを犬のように遅くするように固定しました。ユーザーの各ログインをログに記録するUserLoginHistoryテーブルがあるとします。ユーザーごとに、最初にログインした日付が必要です(クエリの後半で、LogDateでグループ化して、1日に最初にログインした回数を取得します)。

select
    LogDate, --(this value is only date, no time)
    UserId
from
    UserLoginHistory ul
where
    not exists
        (
            select 
                * 
            from 
                UserLoginHistory ulPrevious
            where
                ulPrevious.LogDate < ul.LogDate
                and ul.UserId = ulPrevious.UserId
        )
group by ul.LogDate, ul.UserId

明らかにNOTEXISTS-部分は遅いものです。しかし、同じ仕事をするより効率的なものに置き換える方法がわかりません。

UserLogHistoryカウントが少ない場合、パフォーマンスは問題ありません。それは私が約15000に達するとき、それは遅くなり始めます。たぶん私は毎日の結果を別のテーブルにバッチ処理する必要がありますが、そこに1つあるはずなので、このクエリのより良い解決策を見つけたいと思います...

御時間ありがとうございます!

4

2 に答える 2

4

行番号付け方法を使用できます。

select LogDate,UserId from (
    select
       LogDate, 
       UserId
       row_number() over (partition by UserId order by LogDate) as rown
    from
        UserLoginHistory ul
)
where rown = 1

各 ID の行は LogDate によって番号付けされるため、最も古い行には常に 1 の番号が付けられます。

group by注:元のクエリの は必要ではないと思います。not exists句は、UserId と LogDate の一意の組み合わせのみを取得することを保証する必要があります。

于 2013-03-07T15:53:52.360 に答える
4

関心のあるフィールドがこれら 2 つだけの場合、単純な集計を使用できないでしょうか?

SELECT  LogDate = MIN(LogDate),
        UserID
FROM    UserLoginHistory
GROUP BY UserID;
于 2013-03-07T16:03:11.000 に答える