Baffled with MySQL LEFT JOIN query that I have to speed it up
Your query does not do what you think it does. It results in much more rows than you want to because of the cross join. The only reason you haven't noticed it, is that the excessive number of rows produced are not really inserted in the 3rd table due to duplicate keys which trigger either the INSERT IGNORE or the ON DUPLICATE KEY UPDATE 

(And you should really keep one of these two, there is absolutely no reason to have both IGNORE and ON DUPLICATE KEY UPDATE. MySQL will either ignore the duplicate keys or try to update the existing row. Does it make sense to ignore someone and talk to him at the same time?) 

You probably need:

FROM contacts c
  LEFT JOIN dnc_contacts d 
    ON  d.contact = c.contact
    AND d.group_id = 21
WHERE c.phonebook_id = 70 
  AND d.contact IS NULL


Try the above (just SELECT first, without inserting), to see if it gives you the wanted results.

An index on dnc_contacts (group_id, contact) would help with efficiency.