SELECT
*
FROM
`users`
WHERE
`id` != 1
AND `users`.`activated` = 1
AND NOT EXISTS (
SELECT
1
FROM
`blockings`
WHERE (blockings.user_id = users.id
AND blockings.blocked_id = 1)
OR(blockings.blocked_id = users.id
AND blockings.user_id = 1))
ORDER BY
users.id DESC
LIMIT 10 OFFSET 0
It takes 5 seconds to complete this query on a 30k rows table
It takes a moment to complete when I remove NOT EXISTS part
There is Index on users.id and blockings.user_id and blockings.blocked_id
How can I speed up this query?
2
Answers
This is a bit of a "stab in the dark" as you have not included your table definitions or EXPLAIN output for your current query in your question.
With single column indices on
blockings.user_id
andblockings.blocked_id
you should be seeing an index_merge forblockings
in the EXPLAIN output for your current query.With PK
(user_id, blocked_id)
and an index on(blocked_id, user_id)
using a UNION in your NOT EXISTS is likely to be much faster:As suggested by MatBailie, it is worth trying with the UNION ALL split into two separate NOT EXISTS:
Here is a possible alternative query and you may need to add index on the columns used in the where clause.