0

私は2つのテーブルを持っています:1)ユーザーの資格情報が保存されているユーザー。1000 を超えるユーザー レコードを保持しています。

ID | 名前 | パスワード | ユーザータイプID

2) ログインの詳細が取得される user_logs。そのかなり大きい、つまり 100000 を超えるレコードです。

ID | 名前 | DATEOFLOGIN | ユーザーID | ログインタイプ

指定された 2 つの日付と最後にログインした日付の間にシステムにアクセスしていないユーザーを見つける必要があります。

SELECT MAX(userlogs.dateoflogin) AS lastlogindate,
       u1.id AS Id,
       u1.name AS Name
FROM USER u1
LEFT OUTER JOIN user_logs userlogs ON u1.id = userlogs.userid
WHERE u1.id NOT IN
    ( SELECT userid
     FROM user_logs userlogs2
     WHERE userlogs2.logtype='Login'
       AND userlogs2.dateoflogin BETWEEN '2013-05-10' AND '2013-05-20'
       AND userlogs2.userid IS NOT NULL)
GROUP BY u1.id;

テーブルが保持するレコードが小さい場合は、うまく機能します。しかし、user テーブルに 1000 を超えるレコードがあり、user_logs テーブルに 100000 を超えるレコードがあるライブ システムでは、クエリに非常に長い時間がかかり、成功したかどうかわかりません。:)

上記のクエリを最適化するにはどうすればよいですか。このクエリは、ログインを試みたことのないユーザーも検出します。

4

2 に答える 2

0

これはクエリと同等ですが、多くの場合LEFT JOINNULLチェック付きの は よりも効率的ですNOT IN

SELECT MAX(userlogs.dateoflogin) as lastlogindate , u1.id as Id , u1.name as Name
FROM user  u1
LEFT OUTER JOIN user_logs userlogs ON u1.id = userlogs.userid 
LEFT OUTER JOIN (SELECT distinct userid
                 FROM user_logs  
                 WHERE logtype='Login' 
                 AND dateoflogin BETWEEN '2013-05-10' AND '2013-05-20' 
                 AND userid IS NOT null) userlogs2 ON u1.id = userlogs2.userid
WHERE userlogs2.userid IS NULL
GROUP BY u1.id

dateofloginサブクエリが適切に実行されるように、インデックスがオンになっていることを確認してください。

EXPLAINの出力を両方のクエリと比較します。

于 2013-05-24T10:42:40.270 に答える
0

まず、パフォーマンスを向上させたい場合は、そのサブクエリを変更する必要があります。これらは便利ですが、クエリが大幅に遅くなる傾向があります。

次に、WHERE 句のすべての列にインデックスがあることを確認してください。

于 2013-05-24T10:34:45.267 に答える