Я использую MySQL 5.7 и у меня следующий запрос занимает более 8 сек c для выполнения, что слишком медленно.
explain select distinct `jobs`.*
, CASE WHEN jobs.alt_company_name IS NOT NULL OR job_files.path IS NOT NULL
THEN job_files.path
ELSE company_files.path
END AS logo_path
, `applications`.`created_at` as `application_date`
from `jobs`
inner join `job_status` on `job_status`.`job_id` = `jobs`.`id`
inner join `recruiters` on `recruiters`.`id` = `jobs`.`recruiter_id`
inner join `companies` on `companies`.`id` = `recruiters`.`company_id`
inner join `locations` on `locations`.`id` = `jobs`.`location_id`
inner join `location_name` on `location_name`.`location_id` = `locations`.`id`
inner join `job_language` on `job_language`.`job_id` = `jobs`.`id`
inner join `languages` on `languages`.`id` = `job_language`.`language_id`
inner join `job_industry` on `job_industry`.`job_id` = `jobs`.`id`
left join `job_salary` on `job_salary`.`job_id` = `jobs`.`id`
left join (SELECT fileable_id, MIN(created_at) as min_created_at
FROM files WHERE file_type = "JobLogo" AND fileable_type = "App\\Job"
GROUP BY fileable_id) AS subquery_one on `subquery_one`.`fileable_id` = `jobs`.`id`
left join `files` as `job_files` on `job_files`.`fileable_id` = `subquery_one`.`fileable_id` and `job_files`.`created_at` = `subquery_one`.`min_created_at`
left join (SELECT fileable_id, MIN(created_at) as min_created_at
FROM files WHERE file_type = "CompanyLogo" AND fileable_type = "App\\Company"
GROUP BY fileable_id) AS subquery_two on `subquery_two`.`fileable_id` = `companies`.`id`
left join `files` as `company_files` on `company_files`.`fileable_id` = `subquery_two`.`fileable_id` and `company_files`.`created_at` = `subquery_two`.`min_created_at`
left join `job_shortlist` on `job_shortlist`.`job_id` = `jobs`.`id` and `job_shortlist`.`jobseeker_id` is NULL
left join `applications` on `applications`.`job_id` = `jobs`.`id` and `applications`.`jobseeker_id` is NULL
where (`languages`.`id` in ('1') or `languages`.`parent_id` in ('1'))
and `job_industry`.`industry_id` in ('1', '5','6')
and `jobs`.`contract_type_id` in ('3')
and `jobs`.`contract_hour_id` in ('1')
and `jobs`.`id` <> 6
and `applications`.`id` is NULL
and `jobs`.`start_at` <= '2020-03-13 15:06:29'
and `jobs`.`end_at` >= '2020-03-13 15:06:29'
and `jobs`.`status_id` = 4
order by jobs.start_at desc, jobs.id desc limit 4
Объяснение результатов:
+----+-------------+---------------+------------+--------+-----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+-------------------------------------+------+----------+---------------------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------------+------------+--------+-----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+-------------------------------------+------+----------+---------------------------------------------------------------------+
| 1 | PRIMARY | jobs | NULL | range | PRIMARY,jobs_status_id_foreign,jobs_recruiter_id_foreign,jobs_contract_type_id_foreign,jobs_contract_hour_id_foreign,jobs_location_id_foreign | jobs_status_id_foreign | 8 | NULL | 6 | 16.67 | Using index condition; Using where; Using temporary; Using filesort |
| 1 | PRIMARY | job_language | NULL | ref | PRIMARY,job_language_language_id_foreign | PRIMARY | 4 | testjobsdb.jobs.id | 1 | 100.00 | Using index |
| 1 | PRIMARY | languages | NULL | eq_ref | PRIMARY,languages_parent_id_index | PRIMARY | 4 | testjobsdb.job_language.language_id | 1 | 100.00 | Using where |
| 1 | PRIMARY | job_industry | NULL | eq_ref | PRIMARY,job_industry_industry_id_foreign | PRIMARY | 8 | testjobsdb.jobs.id,const | 1 | 100.00 | Using index |
| 1 | PRIMARY | jobs | NULL | eq_ref | PRIMARY,jobs_status_id_foreign | PRIMARY | 4 | testjobsdb.jobs.id | 1 | 100.00 | NULL |
| 1 | PRIMARY | job_salary | NULL | ref | PRIMARY | PRIMARY | 4 | testjobsdb.jobs.id | 1 | 100.00 | Using index |
| 1 | PRIMARY | recruiters | NULL | eq_ref | PRIMARY,recruiters_company_id_foreign | PRIMARY | 4 | testjobsdb.jobs.recruiter_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | companies | NULL | eq_ref | PRIMARY | PRIMARY | 4 | testjobsdb.recruiters.company_id | 1 | 100.00 | Using index |
| 1 | PRIMARY | status_types | NULL | eq_ref | PRIMARY | PRIMARY | 4 | testjobsdb.jobs.status_id | 1 | 100.00 | Using index |
| 1 | PRIMARY | locations | NULL | eq_ref | PRIMARY | PRIMARY | 4 | testjobsdb.jobs.location_id | 1 | 100.00 | Using index |
| 1 | PRIMARY | t0 | NULL | eq_ref | PRIMARY | PRIMARY | 4 | testjobsdb.jobs.location_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | <derived2> | NULL | ref | <auto_key1> | <auto_key1> | 5 | testjobsdb.jobs.id | 2 | 100.00 | NULL |
| 1 | PRIMARY | job_files | NULL | ALL | NULL | NULL | NULL | NULL | 1712 | 100.00 | Using where; Using join buffer (Block Nested Loop) |
| 1 | PRIMARY | <derived3> | NULL | ref | <auto_key1> | <auto_key1> | 5 | testjobsdb.recruiters.company_id | 2 | 100.00 | NULL |
| 1 | PRIMARY | company_files | NULL | ALL | NULL | NULL | NULL | NULL | 1712 | 100.00 | Using where; Using join buffer (Block Nested Loop) |
| 1 | PRIMARY | job_shortlist | NULL | eq_ref | PRIMARY,job_shortlist_job_id_unique | PRIMARY | 8 | const,testjobsdb.jobs.id | 1 | 100.00 | Using where; Using index |
| 1 | PRIMARY | applications | NULL | eq_ref | applications_job_id_jobseeker_id_unique,applications_jobseeker_id_foreign | applications_job_id_jobseeker_id_unique | 8 | testjobsdb.jobs.id,const | 1 | 25.00 | Using where; Not exists |
| 1 | PRIMARY | t4 | NULL | ref | locations_admin4_feature_code_index | locations_admin4_feature_code_index | 126 | testjobsdb.t0.admin4,const | 3 | 100.00 | Using index; Distinct |
| 1 | PRIMARY | t3 | NULL | ref | locations_admin3_feature_code_index | locations_admin3_feature_code_index | 126 | testjobsdb.t0.admin3,const | 4 | 100.00 | Using index; Distinct |
| 1 | PRIMARY | t2 | NULL | ref | locations_admin2_feature_code_index | locations_admin2_feature_code_index | 366 | testjobsdb.t0.admin2,const | 12 | 100.00 | Using index; Distinct |
| 1 | PRIMARY | t1 | NULL | ref | locations_admin1_feature_code_index | locations_admin1_feature_code_index | 126 | testjobsdb.t0.admin1,const | 70 | 100.00 | Using index; Distinct |
| 3 | DERIVED | files | NULL | ALL | NULL | NULL | NULL | NULL | 1712 | 1.11 | Using where; Using temporary; Using filesort |
| 2 | DERIVED | files | NULL | ALL | NULL | NULL | NULL | NULL | 1712 | 1.11 | Using where; Using temporary; Using filesort |
+----+-------------+---------------+------------+--------+-----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+-------------------------------------+------+----------+---------------------------------------------------------------------+
23 rows in set, 1 warning (8.30 sec)
Если я удаляю условие where and jobs.id <> 6
или удаляем оставленные подзапросы, присоединения, запросы выполняются в соответствии с 0.11 se c
explain select distinct `jobs`.*
, CASE WHEN jobs.alt_company_name IS NOT NULL OR job_files.path IS NOT NULL
THEN job_files.path
ELSE company_files.path
END AS logo_path
, `applications`.`created_at` as `application_date`
from `jobs`
inner join `job_status` on `job_status`.`job_id` = `jobs`.`id`
inner join `recruiters` on `recruiters`.`id` = `jobs`.`recruiter_id`
inner join `companies` on `companies`.`id` = `recruiters`.`company_id`
inner join `locations` on `locations`.`id` = `jobs`.`location_id`
inner join `location_name` on `location_name`.`location_id` = `locations`.`id`
inner join `job_language` on `job_language`.`job_id` = `jobs`.`id`
inner join `languages` on `languages`.`id` = `job_language`.`language_id`
inner join `job_industry` on `job_industry`.`job_id` = `jobs`.`id`
left join `job_salary` on `job_salary`.`job_id` = `jobs`.`id`
left join (SELECT fileable_id, MIN(created_at) as min_created_at
FROM files WHERE file_type = "JobLogo" AND fileable_type = "App\\Job"
GROUP BY fileable_id) AS subquery_one on `subquery_one`.`fileable_id` = `jobs`.`id`
left join `files` as `job_files` on `job_files`.`fileable_id` = `subquery_one`.`fileable_id` and `job_files`.`created_at` = `subquery_one`.`min_created_at`
left join (SELECT fileable_id, MIN(created_at) as min_created_at
FROM files WHERE file_type = "CompanyLogo" AND fileable_type = "App\\Company"
GROUP BY fileable_id) AS subquery_two on `subquery_two`.`fileable_id` = `companies`.`id`
left join `files` as `company_files` on `company_files`.`fileable_id` = `subquery_two`.`fileable_id` and `company_files`.`created_at` = `subquery_two`.`min_created_at`
left join `job_shortlist` on `job_shortlist`.`job_id` = `jobs`.`id` and `job_shortlist`.`jobseeker_id` is NULL
left join `applications` on `applications`.`job_id` = `jobs`.`id` and `applications`.`jobseeker_id` is NULL
where (`languages`.`id` in ('1') or `languages`.`parent_id` in ('1'))
and `job_industry`.`industry_id` in ('1')
and `jobs`.`contract_type_id` in ('3')
and `jobs`.`contract_hour_id` in ('1')
and `applications`.`id` is NULL
and `jobs`.`start_at` <= '2020-03-13 15:06:29'
and `jobs`.`end_at` >= '2020-03-13 15:06:29'
and `jobs`.`status_id` = 4
order by jobs.start_at desc, jobs.id desc limit 4
Объясните результаты:
+----+-------------+---------------+------------+--------+-----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+-------------------------------------+------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------------+------------+--------+-----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+-------------------------------------+------+----------+----------------------------------------------------+
| 1 | PRIMARY | jobs | NULL | ALL | PRIMARY,jobs_status_id_foreign,jobs_recruiter_id_foreign,jobs_contract_type_id_foreign,jobs_contract_hour_id_foreign,jobs_location_id_foreign | NULL | NULL | NULL | 6 | 16.67 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | job_language | NULL | ref | PRIMARY,job_language_language_id_foreign | PRIMARY | 4 | testjobsdb.jobs.id | 1 | 100.00 | Using index |
| 1 | PRIMARY | languages | NULL | eq_ref | PRIMARY,languages_parent_id_index | PRIMARY | 4 | testjobsdb.job_language.language_id | 1 | 100.00 | Using where |
| 1 | PRIMARY | job_industry | NULL | eq_ref | PRIMARY,job_industry_industry_id_foreign | PRIMARY | 8 | testjobsdb.jobs.id,const | 1 | 100.00 | Using index |
| 1 | PRIMARY | jobs | NULL | eq_ref | PRIMARY,jobs_status_id_foreign | PRIMARY | 4 | testjobsdb.jobs.id | 1 | 100.00 | NULL |
| 1 | PRIMARY | job_salary | NULL | ref | PRIMARY | PRIMARY | 4 | testjobsdb.jobs.id | 1 | 100.00 | Using index |
| 1 | PRIMARY | recruiters | NULL | eq_ref | PRIMARY,recruiters_company_id_foreign | PRIMARY | 4 | testjobsdb.jobs.recruiter_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | companies | NULL | eq_ref | PRIMARY | PRIMARY | 4 | testjobsdb.recruiters.company_id | 1 | 100.00 | Using index |
| 1 | PRIMARY | status_types | NULL | eq_ref | PRIMARY | PRIMARY | 4 | testjobsdb.jobs.status_id | 1 | 100.00 | Using index |
| 1 | PRIMARY | locations | NULL | eq_ref | PRIMARY | PRIMARY | 4 | testjobsdb.jobs.location_id | 1 | 100.00 | Using index |
| 1 | PRIMARY | t0 | NULL | eq_ref | PRIMARY | PRIMARY | 4 | testjobsdb.jobs.location_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | <derived2> | NULL | ref | <auto_key1> | <auto_key1> | 5 | testjobsdb.jobs.id | 2 | 100.00 | NULL |
| 1 | PRIMARY | job_files | NULL | ALL | NULL | NULL | NULL | NULL | 1712 | 100.00 | Using where; Using join buffer (Block Nested Loop) |
| 1 | PRIMARY | <derived3> | NULL | ref | <auto_key1> | <auto_key1> | 5 | testjobsdb.recruiters.company_id | 2 | 100.00 | NULL |
| 1 | PRIMARY | company_files | NULL | ALL | NULL | NULL | NULL | NULL | 1712 | 100.00 | Using where; Using join buffer (Block Nested Loop) |
| 1 | PRIMARY | job_shortlist | NULL | eq_ref | PRIMARY,job_shortlist_job_id_unique | PRIMARY | 8 | const,testjobsdb.jobs.id | 1 | 100.00 | Using where; Using index |
| 1 | PRIMARY | applications | NULL | eq_ref | applications_job_id_jobseeker_id_unique,applications_jobseeker_id_foreign | applications_job_id_jobseeker_id_unique | 8 | testjobsdb.jobs.id,const | 1 | 25.00 | Using where; Not exists |
| 1 | PRIMARY | t4 | NULL | ref | locations_admin4_feature_code_index | locations_admin4_feature_code_index | 126 | testjobsdb.t0.admin4,const | 3 | 100.00 | Using index; Distinct |
| 1 | PRIMARY | t3 | NULL | ref | locations_admin3_feature_code_index | locations_admin3_feature_code_index | 126 | testjobsdb.t0.admin3,const | 4 | 100.00 | Using index; Distinct |
| 1 | PRIMARY | t2 | NULL | ref | locations_admin2_feature_code_index | locations_admin2_feature_code_index | 366 | testjobsdb.t0.admin2,const | 12 | 100.00 | Using index; Distinct |
| 1 | PRIMARY | t1 | NULL | ref | locations_admin1_feature_code_index | locations_admin1_feature_code_index | 126 | testjobsdb.t0.admin1,const | 70 | 100.00 | Using index; Distinct |
| 3 | DERIVED | files | NULL | ALL | NULL | NULL | NULL | NULL | 1712 | 1.11 | Using where; Using temporary; Using filesort |
| 2 | DERIVED | files | NULL | ALL | NULL | NULL | NULL | NULL | 1712 | 1.11 | Using where; Using temporary; Using filesort |
+----+-------------+---------------+------------+--------+-----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+-------------------------------------+------+----------+----------------------------------------------------+
23 rows in set, 1 warning (0.11 sec)
Как я могу оптимизировать этот запрос. Любые советы, советы, советы очень ценятся.