Try this. It doesn't appear to impact performance.
Unmodified : 2987 rows in set (1.53 sec)
Modified : 2987 rows in set (1.48 sec)
I had to use GROUP BY to get a single row with
1234 1 1
otherwise, if both matched, it gave
1234 1 0
1234 0 1
Query
SELECT id
, SUM(match_email) as by_email
, SUM(match_phone) as by_phone
FROM (
SELECT
`a1`.`id`,
1 as match_email,
0 as match_phone
FROM
(
(
`customers` `a1`
JOIN `customers` `b1`
ON
(
(
(`a1`.`email` = `b1`.`email`) AND(`a1`.`id` <> `b1`.`id`)
AND(
`a1`.`email` <> 'blah@example.com'
) AND(
`b1`.`email` <> 'blah@example.com'
)
)
)
)
JOIN `quotes` `q1`
ON
(
(
(`q1`.`customer_id` = `b1`.`id`) AND(`q1`.`purchased` = 1)
)
)
)
UNION
SELECT
`a`.`id`,
0 as match_email,
1 as match_phone
FROM
(
(
`customers` `a`
JOIN `customers` `b`
ON
(
(
(`a`.`phone` = `b`.`phone`) AND(`a`.`id` <> `b`.`id`)
)
)
)
JOIN `quotes` `q`
ON
(
(
(`q`.`customer_id` = `b`.`id`) AND(`q`.`purchased` = 1)
)
)
)
) all_matches
GROUP BY
`id`