В зависимости от базы данных для скорости вы можете использовать команду UNION.
SQL длиннее, но, в зависимости от базы данных, он ускоряет работу, разделяя «считать вещи, которые есть» и «считать вещи, которых нет».
(
select page.name, count(page-attachment.id) as attachmentsnumber
from page
inner join page-attachment on page.id=page-id
group by page.id
)
UNION
(
select page.name, 0 as attachmentsnumber
from page
where page.id not in (
select page-id from page-attachment)
)
База данных, для которой мне нужно это решение, содержит 20 страниц в более чем миллионе вложений. UNION заставил его работать за 13 секунд, а не так долго, как мне стало скучно, и я попробовал другой способ (где-то за 60 секунд до того, как я уничтожил методы внешнего соединения и подзапроса).