Если вы возвращали все записи, сортировка не должна занимать много времени, даже если они являются вычисленными/неиндексированными полями. Однако вы используете «Limit 1». Это изменяет подход оптимизатора.
В первом случае вы заказываете удостоверение личности. Поскольку у вас есть «предел 1», а идентификатор, вероятно, имеет индекс, оптимизатор может перейти по идентификатору по ID и когда он получит одну запись, которая соответствует предложению WHERE, которое она может вернуть.
Однако во втором запросе, хотя вам нужна только 1 запись, оптимизатор не знает, какой из них будет, если он не вычислит весь набор (как будто у вас не было «limit 1»), а затем возвращается только первый.
Снимите «LIMIT 1» и сравните два запроса. Если разница остается, это может быть другой проблемой.
Трудно сказать, что лучше всего подходит для ваших томов. Попробуйте этот запрос:
select id, max(date(sent)) as sent, 0 As done
from test2
where exists (select 1 from bin where bin.id=test2.id and num not in (1,2))
group by id
union all
select id, max(date(sent)) as sent, 1 As done
from test2
where exists (select 1 from bin where bin.id=test2.id and num in (1,2))
group by id
order by done, sent
limit 1
SQL Fiddle is here, если вы хотите, чтобы настроить его.
Я оставил тестовый стол, потому что вы не возвращали ни одного поля, кроме ID, которое уже находится на test2. Если вам нужны другие поля из теста, вам придется настроить его.
С большинством современных СУБД, подзапросы на самом деле не хуже Joins. Это справедливо только для старшей СУБД, которая не могла понять, когда эти два эквивалента. Сегодня иногда подзапрос - лучший способ пойти ... все зависит. –