Я хочу выбрать из таблицы, а затем сделать выбор для каждого из них.
столы:
category
+====+=======+
| id | title |
+====+=======+
this table has list of category
email
+====+=======+==========+=============+
| id | eMail | domainId | elseColumns |
+====+=======+==========+=============+
this table has list of emails but domains are in another table
domain
+====+========+=============+
| id | domain | elseColumns |
+====+========+=============+
list of domains which used in email
subscriber_category
+========+============+
| userId | categoryId |
+========+============+
list of emails in categories
Теперь вопрос заключается в том, как я могу перечислить категории и количество писем в них с минимальным временем выполнения? моя попытка ждет 20 секунд для 200000 электронной почты и 20 категории.
SQL:
SELECT category.*,
(SELECT COUNT(DISTINCT subscriber_category.userId) FROM subscriber_category
JOIN email ON email.id=subscriber_category.userId
JOIN domain ON domain.id=email.domainId
WHERE subscriber_category.categoryId=category.id
AND email.blackList=0
AND domain.blackList=0
) AS qty
FROM category WHERE category.userId=1 ORDER BY category.title ASC
Это ваш запрос:
SELECT c.*,
(SELECT COUNT(DISTINCT sc.userId)
FROM subscriber_category sc JOIN
email e
ON e.id = sc.userId JOIN
domain d
ON d.id = e.domainId
WHERE sc.categoryId = c.id AND e.blackList = 0 AND d.blackList = 0
) AS qty
FROM category c
WHERE c.userId = 1
ORDER BY c.title ASC;
Структура вполне разумна и индексы должны помочь производительности. Первый индекс включен category(userId, title, id)
, Этот индекс должен использоваться для WHERE
оговорка ORDER BY
и коррелированный подзапрос.
Далее я предполагаю, что у вас есть индексы на id
столбцы в email
а также domain
, Вы можете сделать их чуть более применимыми к запросу, если вы включите blacklist
пометить как второй столбец в индексе. Что еще более важно, вы хотите индекс на subscriber_category(categoryId, userId)
, Я также рекомендовал бы удалить count(distinct)
если это не нужно.
Других решений пока нет …