0

i want to get all active users in the past 24 hours, and see whether they've interacted with us before. i have the following query:

SELECT $                                                                                                                                                                             
    DISTINCT user_id $                                                                                                                                                               
FROM $                                                                                                                                                                               
    activity $                                                                                                                                                                
WHERE user_id in (SELECT $                                                                                                                                                           
                      DISTINCT user_id $                                                                                                                                             
                  FROM $                                                                                                                                                             
                      activity $                                                                                                                                              
                  WHERE $                                                                                                                                                            
                      date > DATE_SUB(NOW(), INTERVAL 24 HOUR)) AND $                                                                                                                
      date < DATE_SUB(NOW(), INTERVAL 24 HOUR);

i have indexes on user_id and date. can this be made more efficient?

tipu
  • 9,464
  • 15
  • 65
  • 98
  • All most same statement is running inside user_id in! why don't you try just that statement which you have put inside it. Use Explain – Raul Dec 12 '13 at 07:17
  • i did, it was going through too many rows. this is why i came to SO – tipu Dec 12 '13 at 07:39

2 Answers2

0

chris put me in the right track when he instructed me to use EXISTS. the correct query is:

SELECT $                                                                                                                                                                                 DISTINCT user_id $                                                                                                                                                               FROM $                                                                                                                                                                               
    activity o $                                                                                                                                                              
WHERE $                                                                                                                                                                              
    EXISTS (SELECT $                                                                                                                                                                 
                1 $                                                                                                                                                                  
            FROM $                                                                                                                                                                   
                activity i $                                                                                                                                                  
            WHERE $                                                                                                                                                                  
                o.user_id = i.user_id AND $                                                                                                                                          
                DATEDIFF(o.date, i.date) > 0) AND $                                                                                                                                                           
    date > DATE_SUB(NOW(), INTERVAL 24 HOUR)$                       

explain mentioned rows examined went from 20k to 170

tipu
  • 9,464
  • 15
  • 65
  • 98
0

could you try this?

SELECT DISTINCT user_id
FROM activity INNER JOIN
    (
        SELECT DISTINCT user_id
        FROM activity
        WHERE date > DATE_SUB(NOW(), INTERVAL 24 HOUR)
            AND date < DATE_SUB(NOW(), INTERVAL 24 HOUR
    ) x ON x.user_id = activity.user_id

Or

SELECT DISTINCT user_id
FROM activity a1
WHERE EXISTS (
    SELECT 1
    FROM activity a2
    WHERE a2.user_id = a1.user_id
      date > DATE_SUB(NOW(), INTERVAL 24 HOUR))
      AND date < DATE_SUB(NOW(), INTERVAL 24 HOUR
);
Jason Heo
  • 9,956
  • 2
  • 36
  • 64