tb_cv не связан с другими таблицами в подзапросе. Я думаю, что это коренная причина медленного запроса. Это приводит к генерации декартового произведения, в результате чего получается гораздо больше строк, чем вам, вероятно, нужно.
Кроме того, я бы сказал, что вам нужны индексы для tb_jobseeker.created_at
, tb_cv.created_at
и tb_industry.industry_id
, и вы можете захотеть избавиться от вызовов UNIX_TIMESTAMP()
в подзапросе, поскольку они препятствуют использованию индекс. Вместо этого используйте BETWEEN
и фактические значения поля.
Вот моя попытка понять ваш запрос и написать лучшую версию. Я полагаю, вы хотите получить количество новых регистраций соискателей и новых загруженных резюме в месяц для каждой отрасли:
SELECT
i.industry_id,
i.description,
MONTH(j.created_at) AS month_created,
YEAR(j.created_at) AS year_created,
COUNT(DISTINCT j.jobseeker_id) AS new_registrations,
COUNT(cv.cv_id) AS uploaded_cvs
FROM
tb_cv AS cv
INNER JOIN tb_jobseeker AS j ON j.jobseeker_id = cv.jobseeker_id
INNER JOIN tb_industry AS i ON i.industry_id = j.industry_id
WHERE
j.created_at BETWEEN '2009-05-01' AND '2009-05-31'
AND cv.created_at BETWEEN '2009-05-01' AND '2009-05-31'
GROUP BY
i.industry_id,
i.description,
MONTH(j.created_at),
YEAR(j.created_at)
Несколько вещей, которые я заметил при написании запроса:
- значения GROUP BY, которые вы не выводите в конце. Зачем? ( Я добавил сгруппированное поле в список вывода. )
- вы присоединяетесь к трем таблицам в подзапросе, используя только значения из одной из них. Зачем? Я не понимаю, для чего это было бы полезно, кроме как отфильтровывать записи CV, в которых нет соискателей или представителей отрасли & mdash; что мне трудно представить. ( Я удалил весь подзапрос и вместо него использовал простой
COUNT
. )
- Ваш подзапрос каждый раз возвращает одно и то же значение. Возможно, вы хотели как-то соотнести это с отраслью?
- Подзапрос выполняется один раз для каждой записи в сгруппированном запросе, без включения в статистическую функцию.