2

次のように実行するのに48秒かかるクエリがあります。

SELECT count(DISTINCT tmd_logins.userID) as totalLoginsUniqueLast30Days 
FROM tmd_logins
join tmd_users on tmd_logins.userID = tmd_users.userID 
where tmd_users.isPatient = 1 AND loggedIn > '2011-03-25' 
and tmd_logins.userID in 
    (SELECT userID as accounts30Days FROM tmd_users
    where isPatient = 1 AND created > '2012-04-29' AND computerID is null)

キーワードを削除するとDISTINCT1秒もかからないので、ボトルネックはその中にあるようです。

tmd_loginsデータベースは、ユーザーがシステムにログインするたびにテーブルにエントリを追加します。過去30日間など、特定の期間内に作成およびログインされた患者であるすべてのユーザーの総数を取得しようとしています。

DISTINCTキーワードを削除group by tmd_logins.userIDしてステートメントに追加しようとしましたが、パフォーマンスの問題が残っています。

テーブルtmd_loginsには約300,000のレコードがtmd_usersあり、約40,000があります

これを行うためのより良い方法はありますか?

4

1 に答える 1

4

あなたが抱えている問題は実行計画です。私の推測では、「in」句が混乱を招く可能性があります。あなたは試すことができます:

SELECT count(DISTINCT tmd_logins.userID) as totalLoginsUniqueLast30Days 
FROM tmd_logins join
     tmd_users
     on tmd_logins.userID = tmd_users.userID join
     (SELECT distinct userID as accounts30Days
      FROM tmd_users
      where isPatient = 1 AND
            created > '2012-04-29' AND
            computerID is null
     ) t
     on tmd_logins.userID = t.accounts30Days
where tmd_users.isPatient = 1 AND
      loggedIn > '2011-03-25' 

それはうまくいくかもしれないし、うまくいかないかもしれません。ただし、クエリ自体の構造については疑問に思っています。tmd_users というテーブルでは、UserID を区別する必要があるように思われます。その場合は、すべての条件を 1 つにラップできます。

SELECT count(DISTINCT tmd_logins.userID) as totalLoginsUniqueLast30Days 
FROM tmd_logins join
     tmd_users
     on tmd_logins.userID = tmd_users.userID 
where tmd_users.isPatient = 1 AND
      loggedIn > '2011-03-25' and
      created > '2012-04-29' AND
      computerID is null

私の推測が正しければ、これは間違いなく高速に実行されるはずです。

于 2012-05-29T23:46:44.550 に答える