Reputation: 25
I have 2 tables, users
and sessions
. The tables look like this:
users - id
(int), name
(varchar)
sessions - id
(int), user_id
(int), ip
(inet), cookie_identifier
(varchar)
All columns have an index.
Now, I am trying to query all users that have a session with the same ip
or cookie_identifier
as a specific user.
Here is my query:
SELECT *
FROM "users"
WHERE "id" IN
(SELECT "user_id"
FROM "sessions"
WHERE "user_id" <> 1234
AND ("ip" IN
(SELECT "ip"
FROM "sessions"
WHERE "user_id" = 1234
GROUP BY "ip")
OR "cookie_identifier" IN
(SELECT "cookie_identifier"
FROM "sessions"
WHERE "user_id" = 1234
GROUP BY "cookie_identifier"))
GROUP BY "user_id")
The users
table has ~200,000 rows, the sessions
table has ~1.5 million rows. The query takes around 3-5 seconds.
Is it possible to optimize those results?
Upvotes: 0
Views: 728
Reputation: 35583
I would suggest, as a trial, to remove all grouping:
SELECT
*
FROM users
WHERE id IN (
SELECT
user_id
FROM sessions
WHERE user_id <> 1234
AND (ip IN (
SELECT
ip
FROM sessions
WHERE user_id = 1234
)
OR cookie_identifier IN (
SELECT
cookie_identifier
FROM sessions
WHERE user_id = 1234
)
)
)
;
If that isn't helpful, try altering the above to use EXISTS
instead of IN
SELECT
*
FROM users u
WHERE EXISTS (
SELECT
NULL
FROM sessions s
WHERE s.user_id <> 1234
AND u.id = s.user_id
AND EXISTS (
SELECT
NULL
FROM sessions s2
WHERE s2.user_id = 1234
AND (s.ip = s2.ip
OR s.cookie_identifier = s2.cookie_identifier
)
)
)
;
Upvotes: 1