Я думаю, и это только мое мнение, что правильный подход - это считать все вещи. Может быть, проблема в другом месте.
Это то, что я использую для подсчета, и оно работает довольно быстро, даже с большим количеством данных.
SELECT categoryid, COUNT(*) FROM Item GROUP By categoryid
Это даст вам хэш со всеми предметами по категориям. Но это не будет включать пустые категории.
Затем для получения информации о категориях выполните следующее:
SELECT category.* FROM category
INNER JOIN (SELECT categoryid, COUNT(*) AS n FROM Item GROUP By categoryid) AS item
ON category.id = item.categoryid