У меня сложный SQL-запрос, который работает, но его производительность ниже идеальной (выполнение занимает почти 3 секунды). Думаю, я оптимизировал все, что мог придумать, но, может быть, есть кое-что еще, что я до сих пор не могу поймать.
Вот оно:
SELECT DISTINCT doctors.doc_id, doctors.doc_title, doctors.doc_last,
doctors.doc_first, doctors.doc_email, doctors.doc_birthday,
doctors.doc_mobile, doctors.doc_occasional, doctors.doc_fiscal_code,
doctors.doc_register_number, doctors.doc_register_province,
doctors.doc_agreement, doctors.doc_notes, doctors.doc_timestamp,
doctors.doc_deleted, specializations.spe_id, specializations.spe_name,
activities.act_id, activities.act_name,
users.use_id, users.use_last, users.use_first, users.use_active,
(SELECT COUNT(*)
FROM congress
INNER JOIN participants ON participants.par_congress = congress.cng_id
WHERE par_doctor = doc_id
AND congress.cng_from >= '2018-01-01'
AND congress.cng_from <= '2018-07-02')
AS cng_count,
(SELECT COUNT(*)
FROM visits
INNER JOIN reports ON reports.rep_id = visits.vis_report
INNER JOIN locations ON locations.loc_id = visits.vis_location
WHERE visits.vis_doctor = doctors.doc_id
AND locations.loc_structure LIKE '%'
AND reports.rep_dated >= '2018-01-01'
AND reports.rep_dated <= '2018-07-02')
AS vis_count_all,
(SELECT COUNT(*)
FROM visits
INNER JOIN reports ON reports.rep_id = visits.vis_report
INNER JOIN locations ON locations.loc_id = visits.vis_location
WHERE visits.vis_doctor = doctors.doc_id
AND reports.rep_user = users.use_id
AND locations.loc_structure LIKE '%'
AND reports.rep_dated >= '2018-01-01'
AND reports.rep_dated <= '2018-07-02')
AS vis_count_user,
(SELECT COUNT(*)
FROM locations
WHERE locations.loc_doctor = doctors.doc_id )
AS loc_count
FROM doctors
LEFT JOIN locations ON locations.loc_doctor = doctors.doc_id
INNER JOIN specializations ON specializations.spe_id = doctors.doc_specialization
INNER JOIN activities ON activities.act_id = doctors.doc_activity
INNER JOIN users ON users.use_id = doctors.doc_user
WHERE doctors.doc_last IS NOT NULL
AND doctors.doc_id LIKE '%'
AND (locations.loc_province IS NULL OR locations.loc_province LIKE '%')
AND (locations.loc_structure IS NULL OR locations.loc_structure LIKE '%')
AND DATE(doctors.doc_timestamp) <= '2018-07-02'
AND doctors.doc_occasional LIKE '%'
AND doctors.doc_deleted LIKE '0'
AND doctors.doc_agreement LIKE '%'
AND doctors.doc_active
AND users.use_id LIKE '%'
GROUP BY doctors.doc_id
HAVING vis_count_user <> - 1
ORDER BY doctors.doc_last, doctors.doc_first, doctors.doc_id
Реальное узкое место находится на подвыборах vis_count_all
и vis_count_user
(они отличаются только для дополнительного оператора AND reports.rep_user = users.use_id
): удаление их ускоряет запрос
Поскольку они отличаются только утверждением, я не знаю, смогу ли я использовать один из них, чтобы получить другое значение более простым способом
Во всяком случае, я создал все ключи, которые мог придумать, вот результат EXPLAIN

Пожалуйста, какие-нибудь советы по улучшению?
Спасибо