Reputation: 14275
I am having issues with an InnoDB mysql database. E.g., I have two tables, events and events_artists with the following architecture:
events:
id (PK)
host_id
date
events_artists:
id (PK)
event_id
artist_id
The table events has about 100,000 entries, events_artists holds about 150,000.
One of the things I have to do is check for entries in the table events that are not referred to in the table events_artists. To do that, in another post I have received the query
SELECT * FROM events WHERE id IS NULL OR id NOT IN (SELECT event_id FROM events_artists)
From the logic, this query looks good to me. However, it is just extremely slow. I let it run for one hour now, and still no result. Something has to be wrong there.
I am grateful for any help on how to optimize this!
Thanks
Charles
SOLUTION FOUND
The following query makes the statement much faster:
SELECT *
FROM events a
LEFT JOIN events_artists b
ON a.id = b.event_id
WHERE b.event_id IS NULL;
However, the main speed boost was adding foreign keys. I had to remove them in the interim for some duplicate search and added them back now, which increases speed a lot. While the query took more than an hour before, it only takes one second now.
Thank you!
Charles
Upvotes: 1
Views: 94
Reputation: 13700
Try this
select
ev.* from events as ev
left join events_artists as ea on ev.id=ea.event_id
where
ea.event_id is null or ev.id is null
Upvotes: 1
Reputation: 12809
If you run an EXPLAIN
of your query, you'll see the subquery is treated as DEPENDENT
, which means it'll be run once for each row in your events
table, hence it's slow.
You can change it to be independent like so:
SELECT events.*
FROM events
LEFT JOIN events_artists ON (events.id = events_artists.event_id)
WHERE events_artists.event_id IS NULL
Upvotes: 1
Reputation: 29061
To get faster results you should avoid using sub-query. Alternatively you can try using LEFT JOIN to get records which are in events but not in events_artists.
Visit Visual explanation of joins
SELECT *
FROM events a
LEFT JOIN events_artists b
ON a.id = b.event_id
WHERE b.event_id IS NULL;
Also make sure that you have index on columns id and event_id for faster query execution.
Upvotes: 3