Avoiding filesort and query optimization - mysql

I have written a query and optimized it to extent i can. But still query takes 3 minutes to give output.
Please find the below query.
SELECT ps_product.id_product,ps_product_lang.name,pa.id_product_attribute,
pa.`ean13` AS `a_ean13`,MAX(IF((agl.name LIKE "Color"),al.name,'')) AS Color,
MAX(IF((agl.name LIKE "Size"),al.name,'')) AS Size,
ps_product.price,
ps_product_lang.`description`,`ps_product_lang`.`description_short`,`ps_product_lang`.`meta_description`,
`ps_product_lang`.`meta_keywords`,`ps_product_lang`.`meta_title`,pa.`default_on`,
ps_product.`additional_shipping_cost`,
pa.`reference`,
pa.`price`
FROM
`ps_product`
JOIN ps_product_lang ON ps_product_lang.id_product = ps_product.id_product
join ps_product_attribute pa on pa.`id_product` = ps_product.id_product
LEFT JOIN ps_product_attribute_combination pac ON pac.id_product_attribute = pa.id_product_attribute
LEFT JOIN ps_attribute a ON a.id_attribute = pac.id_attribute
LEFT JOIN ps_attribute_group ag ON ag.id_attribute_group = a.id_attribute_group
LEFT JOIN ps_attribute_lang al ON (a.id_attribute = al.id_attribute AND al.id_lang = 1)
LEFT JOIN ps_attribute_group_lang agl ON (ag.id_attribute_group = agl.id_attribute_group AND agl.id_lang = 1)
GROUP BY pa.id_product_attribute ORDER BY ps_product.id_product;
Here is the explain command output
id select_type table type possible_keys key key_len ref rows Extra
------ ----------- --------------- ------ --------------------------------------------------------------------------- ------------------------------------------ ------- ------------------------------- ------ ---------------------------------
1 SIMPLE ps_product ALL PRIMARY (NULL) (NULL) (NULL) 11378 Using temporary; Using filesort
1 SIMPLE pa ref product_attribute_product,product_default product_attribute_product 4 catalog.ps_product.id_product 2
1 SIMPLE pac ref id_product_attribute id_product_attribute 4 catalog.pa.id_product_attribute 1 Using index
1 SIMPLE a eq_ref PRIMARY PRIMARY 4 catalog.pac.id_attribute 1
1 SIMPLE ag eq_ref PRIMARY PRIMARY 4 catalog.a.id_attribute_group 1 Using index
1 SIMPLE al ref id_lang,ps_attribute_lang_lang_idx,ps_attribute_lang_attribute_idx ps_attribute_lang_attribute_idx 4 catalog.a.id_attribute 1
1 SIMPLE agl ref ps_attribute_group_lang_attributegroup_idx,ps_attribute_group_lang_lang_idx ps_attribute_group_lang_attributegroup_idx 4 catalog.ag.id_attribute_group 1
1 SIMPLE ps_product_lang ref ps_product_lang_product_lang_shop,ps_product_lang_product_idx ps_product_lang_product_lang_shop 4 catalog.ps_product.id_product 3
Is there any way i can improve performance.
Here are the create statements.
CREATE TABLE `ps_product` (
`id_product` int(10) unsigned NOT NULL AUTO_INCREMENT,
`id_supplier` int(10) unsigned DEFAULT NULL,
`id_manufacturer` int(10) unsigned DEFAULT NULL,
`id_category_default` int(10) unsigned DEFAULT NULL,
`id_shop_default` int(10) unsigned NOT NULL DEFAULT '1',
`id_tax_rules_group` int(11) unsigned NOT NULL,
`on_sale` tinyint(1) unsigned NOT NULL DEFAULT '0',
`online_only` tinyint(1) unsigned NOT NULL DEFAULT '0',
`ean13` varchar(13) DEFAULT NULL,
`upc` varchar(12) DEFAULT NULL,
`ecotax` decimal(17,6) NOT NULL DEFAULT '0.000000',
`quantity` int(10) NOT NULL DEFAULT '0',
`minimal_quantity` int(10) unsigned NOT NULL DEFAULT '1',
`price` decimal(20,6) NOT NULL DEFAULT '0.000000',
`wholesale_price` decimal(20,6) NOT NULL DEFAULT '0.000000',
`unity` varchar(255) DEFAULT NULL,
`unit_price_ratio` decimal(20,6) NOT NULL DEFAULT '0.000000',
`additional_shipping_cost` decimal(20,2) NOT NULL DEFAULT '0.00',
`reference` varchar(32) DEFAULT NULL,
`supplier_reference` varchar(32) DEFAULT NULL,
`location` varchar(64) DEFAULT NULL,
`width` decimal(20,6) NOT NULL DEFAULT '0.000000',
`height` decimal(20,6) NOT NULL DEFAULT '0.000000',
`depth` decimal(20,6) NOT NULL DEFAULT '0.000000',
`weight` decimal(20,6) NOT NULL DEFAULT '0.000000',
`out_of_stock` int(10) unsigned NOT NULL DEFAULT '2',
`quantity_discount` tinyint(1) DEFAULT '0',
`customizable` tinyint(2) NOT NULL DEFAULT '0',
`uploadable_files` tinyint(4) NOT NULL DEFAULT '0',
`text_fields` tinyint(4) NOT NULL DEFAULT '0',
`active` tinyint(1) unsigned NOT NULL DEFAULT '0',
`available_for_order` tinyint(1) NOT NULL DEFAULT '1',
`available_date` date NOT NULL,
`condition` enum('new','used','refurbished') NOT NULL DEFAULT 'new',
`show_price` tinyint(1) NOT NULL DEFAULT '1',
`indexed` tinyint(1) NOT NULL DEFAULT '0',
`visibility` enum('both','catalog','search','none') NOT NULL DEFAULT 'both',
`cache_is_pack` tinyint(1) NOT NULL DEFAULT '0',
`cache_has_attachments` tinyint(1) NOT NULL DEFAULT '0',
`is_virtual` tinyint(1) NOT NULL DEFAULT '0',
`cache_default_attribute` int(10) unsigned DEFAULT NULL,
`date_add` datetime NOT NULL,
`date_upd` datetime NOT NULL,
`advanced_stock_management` tinyint(1) NOT NULL DEFAULT '0',
`style_guide_url` varchar(100) DEFAULT NULL,
`sequence` int(10) DEFAULT '0',
`a_createddate` datetime DEFAULT NULL,
`a_createdby` bigint(20) DEFAULT NULL,
`a_modifieddate` datetime DEFAULT NULL,
`a_modifiedby` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id_product`),
KEY `product_supplier` (`id_supplier`),
KEY `product_manufacturer` (`id_manufacturer`),
KEY `id_category_default` (`id_category_default`),
KEY `indexed` (`indexed`),
KEY `date_add` (`date_add`),
KEY `ps_product.active_ind` (`active`)
)
and
CREATE TABLE `ps_product_lang` (
`a_productlangid` int(11) NOT NULL AUTO_INCREMENT,
`id_product` int(10) unsigned NOT NULL,
`id_shop` int(11) unsigned NOT NULL DEFAULT '1',
`id_lang` int(10) unsigned NOT NULL,
`description` text,
`description_short` text,
`link_rewrite` varchar(128) NOT NULL,
`meta_description` varchar(255) DEFAULT NULL,
`meta_keywords` varchar(255) DEFAULT NULL,
`meta_title` varchar(128) DEFAULT NULL,
`name` varchar(128) NOT NULL,
`available_now` varchar(255) DEFAULT NULL,
`available_later` varchar(255) DEFAULT NULL,
`a_createddate` datetime DEFAULT NULL,
`a_createdby` bigint(20) DEFAULT NULL,
`a_modifieddate` datetime DEFAULT NULL,
`a_modifiedby` bigint(20) DEFAULT NULL,
PRIMARY KEY (`a_productlangid`,`id_product`,`id_shop`,`id_lang`),
UNIQUE KEY `ps_product_lang_product_lang_shop` (`id_product`,`id_shop`,`id_lang`),
KEY `id_lang` (`id_lang`),
KEY `name` (`name`),
KEY `ps_product_lang_product_idx` (`id_product`),
KEY `ps_product_lang_shop_idx` (`id_shop`),
CONSTRAINT `ps_product_lang_lang` FOREIGN KEY (`id_lang`) REFERENCES `ps_lang` (`id_lang`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `ps_product_lang_product` FOREIGN KEY (`id_product`) REFERENCES `ps_product` (`id_product`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `ps_product_lang_shop` FOREIGN KEY (`id_shop`) REFERENCES `ps_shop` (`id_shop`) ON DELETE NO ACTION ON UPDATE NO ACTION
)

Related

How can I optimize this query further?

This is mysql query to which I have added the indexes wherever possible. This is written by some previous coders and I need to optimize it as coming in slow logs. I have following stats for this query:
rows_sent: 1
query_time: 00:10:31
lock_time: 00:00:00
rows_examined: 628241089
db: singledb_ed
last_insert_id: 0
insert_id: 0
server_id: 1789791470
sql_text: SELECT cs.delivery_consultant_id AS user_id,
interview.id AS interview_id,
date(interview.interview_date) AS interview_date,
date(interview.mod_date) AS interview_mod_date,
count(interview.id) AS kpi_item_count,
cu.division_id,
bu.organisation_id,
ctu.team_id
FROM es_shortlist AS cs
LEFT JOIN tms_vacancies AS vac ON cs.vacancy_id = vac.id
LEFT JOIN es_applications AS app ON app.vacancy_id = vac.id AND app.candidate_id = cs.candidate_id
LEFT JOIN tms_interviews AS interview ON app.id = interview.application_id
LEFT JOIN company_users AS cu ON cu.id = cs.delivery_consultant_id
LEFT JOIN base_users AS bu ON bu.company_user_id = cs.delivery_consultant_id AND bu.company_id = cu.base_company_id
LEFT JOIN company_team_users AS ctu ON ctu.user_id = cs.delivery_consultant_id
WHERE (ctu.end_date is null
AND cs.delivery_consultant_id ='53521')
AND (ctu.end_date IS NULL)
AND (ctu.status = 2)
GROUP BY cs.delivery_consultant_id, ctu.team_id
EXPLAIN RESULT:
+----+-------------+-----------+--------+-----------------------------------------------------------+------------------------+---------+---------------------------------------+------+------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+--------+-----------------------------------------------------------+------------------------+---------+---------------------------------------+------+------------------------------------+
| 1 | SIMPLE | cs | ref | delivery_consultant_id | delivery_consultant_id | 5 | const | 1421 | Using temporary; Using filesort |
| 1 | SIMPLE | vac | eq_ref | PRIMARY | PRIMARY | 4 | singledb_ed.cs.vacancy_id | 1 | Using index |
| 1 | SIMPLE | app | ref | vacancy_id,candidate_stage_sync | vacancy_id | 5 | singledb_ed.vac.id | 1 | Using where |
| 1 | SIMPLE | interview | ref | application_id | application_id | 4 | singledb_ed.app.id | 1 | NULL |
| 1 | SIMPLE | cu | eq_ref | PRIMARY | PRIMARY | 4 | singledb_ed.cs.delivery_consultant_id | 1 | NULL |
| 1 | SIMPLE | bu | ref | company_user_id,company_id,getOrganisation,get_index_comp | company_user_id | 5 | singledb_ed.cs.delivery_consultant_id | 1 | Using where |
| 1 | SIMPLE | ctu | ref | user_id,status,end_date | end_date | 6 | const | 40 | Using index condition; Using where |
+----+-------------+-----------+--------+-----------------------------------------------------------+------------------------+---------+---------------------------------------+------+------------------------------------+
Please see this image for EXPLAIN result of this query
The CREATE INFO for all Tables
CREATE TABLE `es_shortlist` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`vacancy_id` int(11) DEFAULT NULL,
`candidate_id` int(11) DEFAULT NULL,
`shortlist_status` tinyint(2) DEFAULT NULL COMMENT '1 = open / 0 = closed / 2 = inprocess',
`created_user_id` int(11) DEFAULT NULL,
`created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`entity_id` int(11) DEFAULT NULL,
`base_company_id` int(11) DEFAULT NULL,
`delivery_consultant_id` int(11) DEFAULT NULL,
`is_cb_migrated` tinyint(2) DEFAULT NULL,
`rs_app_id` int(11) DEFAULT NULL,
`shortlist_source` tinyint(4) DEFAULT '1' COMMENT '1=''System'', 2=''Web Response''',
`shortlist_source_id` int(11) DEFAULT NULL COMMENT '24=''job board'', 43=''indeed'', 44=''google'', ''other is direct''',
PRIMARY KEY (`id`),
KEY `delivery_consultant_id` (`delivery_consultant_id`),
KEY `candidate_id` (`candidate_id`),
KEY `vacancy_id` (`vacancy_id`),
KEY `created_user_id` (`created_user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=39388 DEFAULT CHARSET=utf8;
CREATE TABLE `tms_vacancies` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`base_company_id` int(11) NOT NULL,
`organisation_id` int(11) DEFAULT NULL,
`ref_id` int(11) DEFAULT NULL COMMENT 'ref for vacancy_id',
`eb_reff_id` int(11) DEFAULT NULL,
`team_id` int(11) DEFAULT '0' COMMENT 'attach id of tms_teams table',
`function_id` int(11) DEFAULT NULL,
`division_id` int(11) DEFAULT NULL,
`qualified` tinyint(4) DEFAULT NULL,
`lead_type` tinyint(4) DEFAULT '0' COMMENT '0 - was not a lead,1 - was a lead initially',
`lead_category` tinyint(1) DEFAULT NULL COMMENT 'If in lead_type field value set as 1 then must be set 5 = Market Info, 6 = Hot Lead, 7 = Job Ad',
`source` tinyint(2) DEFAULT NULL,
`search_type` tinyint(4) DEFAULT NULL,
`job_type` tinyint(4) DEFAULT NULL COMMENT '1-contract, 2-permanent and 3-part time etc\n',
`reason` tinyint(4) DEFAULT NULL COMMENT 'Reason for vacancy, try to get that info at the time of creating lead\n\nEg.\nNew Role / \r\n\r\nReplacement - Resignation / Maternity / Sickness / Replacement - Internal Transfer / Replacement - Dismissed',
`job_title` varchar(100) DEFAULT NULL,
`account_id` int(11) DEFAULT NULL COMMENT 'look up - ACCOUNTS OBJECT (NOTICE. An account have to be created before adding a LEAD)',
`start_date` timestamp NULL DEFAULT NULL,
`end_date` timestamp NULL DEFAULT NULL,
`base_salary` double DEFAULT NULL COMMENT 'This field is used to store min value of base salary for permanent type of job',
`base_salary_upto` double DEFAULT NULL COMMENT 'This field is used to store max value of base salary for permanent type of job',
`base_salary_to` double DEFAULT NULL COMMENT 'This field is used to store min value of total package for permanent type of job',
`base_salary_to_upto` double DEFAULT NULL COMMENT 'This field is used to store max value of total package for permanent type of job',
`salary_in_base_currency` double DEFAULT NULL COMMENT 'Base Salary converted into base currecy',
`package_in_base_currency` double DEFAULT NULL COMMENT 'Total Package converted into base currecy',
`application_form_status` tinyint(1) DEFAULT NULL COMMENT 'This Field will show if a vacancy has application created against it or not',
`application_auto_reject_flag` tinyint(1) DEFAULT NULL,
`application_reject_score` tinyint(3) DEFAULT NULL,
`branch_office` int(11) DEFAULT NULL,
`approval_status` tinyint(1) DEFAULT NULL COMMENT '0=>Unapproved, 1=>Approved',
`role_id` int(11) DEFAULT NULL,
`rs_sc_id` int(11) DEFAULT NULL,
`rs_sc_name` varchar(255) DEFAULT NULL,
`rs_sc_email` varchar(255) DEFAULT NULL,
`endorsed_vacancy` tinyint(1) NOT NULL DEFAULT '0',
`percentage_agreed` varchar(255) DEFAULT NULL,
`fee_agreed` double DEFAULT NULL,
`fee_agreed_in_base_currency` double DEFAULT NULL COMMENT 'Fee converted into base currecy',
`excange_rate` double DEFAULT NULL COMMENT 'curreny exchange rate for current month',
`fee_calculation_from` tinyint(2) DEFAULT NULL,
`other_fee` varchar(55) DEFAULT NULL,
`flag_qualified` varchar(55) DEFAULT NULL,
`desc_background_cover` varchar(255) DEFAULT NULL,
`currency` smallint(6) DEFAULT NULL,
`bonus` varchar(250) DEFAULT NULL,
`benefits` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`no_required` tinyint(4) DEFAULT NULL COMMENT 'how many positions are to fill',
`placement_nos` int(11) DEFAULT '0' COMMENT 'no of placement done against vacancy_id',
`summary` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`jobpost_summary` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '1-poen, 2-closed, 3-placed',
`priority` tinyint(1) DEFAULT NULL,
`status_reason` tinyint(4) DEFAULT NULL,
`3ff_status` tinyint(1) DEFAULT '0',
`contract_length` tinyint(4) DEFAULT NULL,
`base_rate` double DEFAULT NULL,
`function` int(11) DEFAULT NULL,
`duration` int(5) DEFAULT NULL,
`expenses` varchar(255) DEFAULT NULL,
`working_commitment` int(11) DEFAULT '100',
`base_rate_to` double DEFAULT NULL,
`daily_client_rate` double DEFAULT NULL COMMENT 'calculate if rate is hourly we save client rate * 8 otherwise as it is client rate',
`daily_candidate_rate` double DEFAULT NULL COMMENT 'calculate if rate is hourly we save candidate rate * 8 otherwise as it is candidate rate',
`client_rate_in_base_curreny` double DEFAULT NULL COMMENT 'Client rate converted into base currecy',
`candidate_rate_in_base_currency` double DEFAULT NULL COMMENT 'Candidate rate converted into base currecy',
`candidate_base_rate` double DEFAULT NULL,
`rate_type` int(11) DEFAULT NULL,
`exp_included` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`base_rate_currency` tinyint(4) DEFAULT NULL,
`job_description` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`client_job_description` text,
`interview_template_id` int(11) DEFAULT NULL,
`application_template_id` int(11) DEFAULT NULL,
`last_mod_user_id` int(11) DEFAULT NULL,
`mod_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`created_user_id` int(11) DEFAULT NULL,
`created_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`closed_date` timestamp NULL DEFAULT NULL,
`flag_post_jobboard` tinyint(1) DEFAULT '0',
`flag_post_supplier` tinyint(1) DEFAULT '0',
`flag_post_tpool` tinyint(1) DEFAULT '0',
`flag_post_social` tinyint(1) DEFAULT '0',
`flag_post_referral` tinyint(1) DEFAULT '0',
`flag_relocate` int(11) DEFAULT '0' COMMENT '0=> job will allow candidate that are not wiiling to relocate ,1=> job will allow candidate that are willing to relocate',
`rs_summary` text,
`created_a_date` timestamp NULL DEFAULT NULL,
`created_b_date` timestamp NULL DEFAULT NULL,
`created_lead_date` timestamp NULL DEFAULT NULL,
`is_teaser` tinyint(1) DEFAULT '0',
`is_pitched` tinyint(4) NOT NULL DEFAULT '0',
`is_block` tinyint(4) NOT NULL DEFAULT '0',
`job_role_id` varchar(56) DEFAULT NULL COMMENT 'combination of jobrole_id and category_id(like 8117##8), ## is seperator',
`search_by` tinyint(4) DEFAULT NULL COMMENT '1 : All of the Skill, 2: Any of the skill',
`is_removed` tinyint(2) DEFAULT NULL,
`is_third_rep` tinyint(1) DEFAULT '0',
`is_cb_migrated` tinyint(4) DEFAULT '0',
`is_eb_migrated` tinyint(4) DEFAULT '0',
`is_posting_approved` tinyint(2) DEFAULT NULL,
`is_posted` tinyint(2) DEFAULT NULL,
`merge_account_id` int(11) DEFAULT NULL,
`rs_vacancy_id` int(11) DEFAULT NULL,
`migrated_date` datetime DEFAULT NULL,
`is_onhold_closeplaced` tinyint(1) DEFAULT '0' COMMENT '0=Not, 1=Close Application of on hold & closed placed jobs more than 30 days old',
`cron_first_grade_a_job_dm` tinyint(4) NOT NULL,
`cron_first_grade_a_job_acc` tinyint(4) NOT NULL,
`fee_agreed_gbp` double DEFAULT NULL,
`fee_agreed_usd` double DEFAULT NULL,
`fee_agreed_eur` double DEFAULT NULL,
`fee_cron_updated` tinyint(1) DEFAULT '0',
`org_id_updated` tinyint(4) DEFAULT '0',
`teamid_updated` tinyint(4) NOT NULL DEFAULT '0',
`is_digital` int(4) NOT NULL DEFAULT '0' COMMENT '0=>deactive,1=>active',
`is_new` tinyint(2) DEFAULT NULL COMMENT '1-New Job',
PRIMARY KEY (`id`),
KEY `base_company_id` (`base_company_id`),
KEY `tms_vacancy_idx` (`function_id`,`status`,`flag_post_jobboard`,`flag_post_supplier`,`flag_post_tpool`),
KEY `organisation_id` (`organisation_id`),
KEY `status` (`status`),
KEY `created_date` (`created_date`),
KEY `job_close` (`organisation_id`,`status`,`created_date`),
KEY `is_new` (`is_new`)
) ENGINE=InnoDB AUTO_INCREMENT=80611 DEFAULT CHARSET=utf8 COMMENT='Tabe for storing lead details by recruiters.\n\nA lead is a co';
CREATE TABLE `es_applications` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`candidate_id` int(11) DEFAULT NULL,
`base_company_id` int(11) DEFAULT NULL,
`dm_id` int(11) DEFAULT NULL,
`current_status` varchar(11) CHARACTER SET latin1 DEFAULT NULL,
`is_active_batch` tinyint(11) DEFAULT NULL COMMENT '1 if current batch, 0 if batch deactive',
`rejection_stage` tinyint(5) DEFAULT '0',
`rejection_status` tinyint(5) DEFAULT NULL COMMENT 'reason for rejection',
`rejection_status_reason` text CHARACTER SET latin1 COMMENT 'comments for rejection',
`rejection_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` int(11) DEFAULT NULL,
`to_user_id` int(11) DEFAULT NULL,
`to_user_type` tinyint(4) DEFAULT NULL COMMENT 'dm/HR or Line Manager',
`from_user_type` tinyint(5) DEFAULT '0' COMMENT 'dm/HR or Line Manager',
`start_date` datetime DEFAULT NULL,
`end_date` datetime DEFAULT NULL,
`sharedby_user` int(11) DEFAULT NULL,
`sharedby_date` timestamp NULL DEFAULT NULL,
`created_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`mod_by` int(11) DEFAULT NULL,
`mod_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`current_sub_status` tinyint(2) DEFAULT NULL,
`application_id` int(11) DEFAULT '0',
`app_stage` int(11) DEFAULT '0' COMMENT 'application stage',
`enterprise_user_id` int(11) DEFAULT NULL,
`enterprise_user_company_id` int(11) DEFAULT NULL,
`cv_send_id` int(11) DEFAULT NULL,
`edmgr_vacancy_id` int(11) DEFAULT NULL,
`vacancy_id` int(11) DEFAULT NULL,
`job_branch_id` int(11) DEFAULT NULL COMMENT 'Branch id of job',
`talent_id` int(11) DEFAULT NULL,
`app_status` int(4) DEFAULT NULL,
`stage_reached` int(4) DEFAULT NULL,
`stage_reached_date` datetime DEFAULT NULL,
`summary` text CHARACTER SET latin1,
`is_available` tinyint(5) DEFAULT '1' COMMENT '1 for available and 0 for not available',
`candidate_type` tinyint(5) DEFAULT '2' COMMENT '2=permanent, 3= contract',
`send_list_id` int(11) DEFAULT NULL COMMENT 'Primary id of es_endorsed_send_list table ',
`is_direct` tinyint(1) DEFAULT '0' COMMENT '0 - not direct, 1 - direct application',
`is_hot` tinyint(1) DEFAULT '0' COMMENT '1 - Hot, 0 - Not Hot',
`organisation_id` int(11) DEFAULT NULL,
`candidate_source` int(11) DEFAULT NULL,
`candidate_source_id` int(11) DEFAULT NULL,
`rs_app_id` int(11) DEFAULT NULL,
`is_teaser` tinyint(1) DEFAULT '0',
`branch_id` int(11) DEFAULT NULL,
`merge_account_id` int(11) DEFAULT NULL,
`entity_org_id` int(5) NOT NULL DEFAULT '0',
`team_id` int(11) DEFAULT NULL,
`orgid_teamid_updated` tinyint(4) DEFAULT '0',
`application_type` smallint(4) DEFAULT NULL,
`es_talent_profile` int(11) DEFAULT NULL,
`entity_id` int(11) DEFAULT NULL,
`is_sourcechain_account` int(11) DEFAULT NULL,
`team_cron` tinyint(2) DEFAULT '0',
`is_cb_migrated` tinyint(4) DEFAULT NULL,
`is_eb_migrated` tinyint(5) NOT NULL DEFAULT '0',
`is_tr_cron` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `dm_id` (`dm_id`),
KEY `current_status` (`current_status`,`cv_send_id`,`vacancy_id`),
KEY `vacancy_id` (`vacancy_id`),
KEY `candidate_stage_sync` (`candidate_id`,`app_status`,`current_sub_status`),
KEY `start_date` (`base_company_id`,`dm_id`) USING BTREE,
KEY `start_date_2` (`start_date`)
) ENGINE=InnoDB AUTO_INCREMENT=112073 DEFAULT CHARSET=utf8;
CREATE TABLE `tms_interviews` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`base_company_id` int(11) NOT NULL,
`stage` int(11) NOT NULL COMMENT 'whether it is 1st or 2nd or 3rd or final.',
`sub_stage` int(11) DEFAULT NULL COMMENT 'it will hold total count of interview for same application',
`ref_id` int(11) DEFAULT NULL COMMENT 'ref for interviewer_id',
`interviewer_id` int(11) NOT NULL,
`interview_date` datetime DEFAULT NULL COMMENT 'interview date .',
`interview_time` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'interview time .',
`interview_type` tinyint(2) DEFAULT NULL COMMENT '1=>FTF, 2=>telephonic',
`status` int(11) DEFAULT NULL COMMENT 'could be accepted or rejected.',
`status_date` datetime DEFAULT NULL,
`status_reason` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'the reason why candidate is rejected at this stage.',
`application_id` int(11) NOT NULL,
`candidate_id` int(11) NOT NULL,
`vacancy_id` int(11) NOT NULL,
`account_id` int(11) NOT NULL,
`account_table` varchar(45) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`client_feedback` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`candidate_feedback` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`cp_feedback` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`note` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`created_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_user_id` int(11) NOT NULL,
`mod_date` timestamp NULL DEFAULT NULL,
`last_mod_user_id` int(11) DEFAULT NULL,
`reff_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`performance_cron_status` tinyint(1) NOT NULL DEFAULT '0',
`time_zone` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`confirmation_flag` tinyint(2) DEFAULT '0',
`interview_where` tinyint(4) DEFAULT NULL COMMENT 'used for where field in interview scheduling',
`location` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`is_cancelled` int(1) NOT NULL DEFAULT '0',
`no_of_reschedules` int(3) DEFAULT '0' COMMENT 'No of reschedules',
`merge_account_id` int(11) DEFAULT NULL,
`team_id` int(11) DEFAULT NULL,
`team_cron` tinyint(2) DEFAULT '0',
`is_cb_migrated` tinyint(4) DEFAULT NULL,
`is_eb_migrated` tinyint(5) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `tms_interviews_idx` (`stage`,`interviewer_id`,`status`) USING BTREE,
KEY `application_id` (`application_id`),
KEY `candidate_id` (`candidate_id`),
KEY `vacancy_id` (`vacancy_id`)
) ENGINE=InnoDB AUTO_INCREMENT=60447 DEFAULT CHARSET=utf8 COMMENT='store interview stages for candidates for particular applica';
CREATE TABLE `company_users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`dpn_sent` tinyint(4) DEFAULT '1' COMMENT 'Pending(1) | Sent(2) | Bounced(3) | Verified(4)',
`email_verification_status` tinyint(4) DEFAULT NULL COMMENT '1:Good, 2: Bad',
`dpn_due_date` datetime DEFAULT '2018-06-24 00:00:00',
`base_company_id` int(11) DEFAULT NULL,
`ref_id` int(11) DEFAULT NULL,
`base_user_id` int(11) DEFAULT NULL,
`branch_id` int(11) DEFAULT NULL,
`client_portal_id` int(11) DEFAULT NULL COMMENT 'client portal id if user is of client portal',
`crm_people_id` int(11) DEFAULT NULL COMMENT 'client user id-people_id',
`education_level` int(11) DEFAULT NULL,
`division_id` int(11) DEFAULT NULL,
`job_level` int(11) DEFAULT NULL,
`fname` varchar(50) DEFAULT NULL,
`lname` varchar(50) DEFAULT NULL,
`title` tinyint(4) DEFAULT NULL,
`job_title` varchar(100) DEFAULT NULL,
`sex` tinyint(1) DEFAULT NULL,
`dob` datetime DEFAULT NULL,
`country_id` int(4) DEFAULT NULL COMMENT 'no constraint should be made on this',
`picture` varchar(255) DEFAULT NULL,
`timezone` varchar(255) DEFAULT NULL,
`function_id` int(11) DEFAULT NULL,
`default_module_id` int(11) DEFAULT NULL,
`status` tinyint(1) DEFAULT NULL COMMENT 'verified, activated, deactivated, approved',
`endorsed_user` tinyint(1) DEFAULT '0',
`endorsed_dm_status` int(11) DEFAULT '1',
`created_user_id` int(11) DEFAULT NULL,
`created_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`last_mod_user_id` int(11) DEFAULT NULL,
`mod_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_onboarding_message` tinyint(1) DEFAULT '0' COMMENT '0=>not onboarding,1=>onboarded',
`is_onboarding_connection` tinyint(1) DEFAULT '0' COMMENT '0=>not onboarding,1=>onboarded',
`is_onboarding_profile` tinyint(1) DEFAULT '0' COMMENT '0=>not onboarding,1=>onboarded',
`hub_integrated` tinyint(4) DEFAULT '0' COMMENT '0:NotIntegrated, 1:Integrated',
`hub_id` bigint(20) DEFAULT NULL,
`cloud_integrated` tinyint(4) DEFAULT '0',
`cloud_contact_id` varchar(255) DEFAULT NULL,
`cloud_integrated_eb` tinyint(4) DEFAULT '0',
`cloud_contact_id_eb` varchar(255) DEFAULT NULL,
`cloud_integrated_tr` tinyint(4) DEFAULT '0',
`cloud_contact_id_tr` varchar(255) DEFAULT NULL,
`is_cb_migrated` tinyint(4) DEFAULT '0',
`is_eb_migrated` tinyint(5) NOT NULL DEFAULT '0',
`eb_reff_id` int(11) DEFAULT NULL,
`is_marketing_org_sync` tinyint(4) DEFAULT '2',
`field_hub_sync` tinyint(4) DEFAULT '0' COMMENT '0:No;1:Yes',
`is_jt_synced` tinyint(4) DEFAULT '0' COMMENT '0:no;1:yes',
`cloud_integrated_vado` tinyint(4) DEFAULT '0',
`cloud_contact_id_vado` int(11) DEFAULT NULL,
`merge_account_id` int(11) DEFAULT NULL,
`is_dm_emp_hub_sync` tinyint(4) DEFAULT '0',
`flag_missing_name` tinyint(2) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `status` (`status`,`client_portal_id`),
KEY `mod_date` (`mod_date`),
KEY `base_company_id` (`base_company_id`),
KEY `created_user_id` (`created_user_id`),
KEY `last_mod_user_id` (`last_mod_user_id`),
KEY `hub_id` (`hub_id`),
KEY `branch_id` (`branch_id`),
KEY `endorsed_user_status` (`endorsed_user`,`status`),
KEY `base_user_id` (`base_user_id`),
KEY `endorsed_user` (`endorsed_user`),
KEY `hub_integrated` (`hub_integrated`),
KEY `dm_hub_employer` (`hub_id`,`is_dm_emp_hub_sync`,`endorsed_user`),
KEY `cv_mod_created_date` (`created_date`,`is_eb_migrated`),
KEY `job_level` (`job_level`),
KEY `function_id` (`function_id`)
) ENGINE=InnoDB AUTO_INCREMENT=555665 DEFAULT CHARSET=utf8;
CREATE TABLE `base_users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`is_eb_migrated` tinyint(4) DEFAULT '0',
`eb_reff_id` bigint(20) DEFAULT NULL,
`account_number` varchar(255) DEFAULT NULL,
`emp_uniq_id` varchar(255) DEFAULT NULL,
`company_id` int(11) DEFAULT NULL,
`company_user_id` int(11) DEFAULT NULL,
`joblevel_id` int(11) DEFAULT NULL,
`type` tinyint(4) DEFAULT NULL,
`username` varchar(100) DEFAULT NULL,
`password` char(32) DEFAULT NULL,
`fname` varchar(45) DEFAULT NULL,
`lname` varchar(45) DEFAULT NULL,
`endorsed_user_email` varchar(255) DEFAULT NULL,
`verification_code` varchar(100) DEFAULT NULL,
`pass_recovery_code` varchar(100) DEFAULT NULL,
`status` tinyint(4) DEFAULT NULL COMMENT 'verified, activated, deactivated, approved',
`ip_addresses` text,
`flag_eb` tinyint(1) DEFAULT NULL COMMENT '0 - NOT EB, 1 - EB User',
`flag_ed_manual` tinyint(2) DEFAULT '0' COMMENT '0 - NOT READ, 1 - READ. Its for verifying whether the user/DM is aware of Endorsed client manual.',
`ip_verify` tinyint(1) DEFAULT '0',
`hubspot_flag` int(11) DEFAULT NULL COMMENT '1=active, 2=deactive',
`organisation_id` int(11) DEFAULT NULL COMMENT 'xero organisation id for ed manager users',
`last_mod_user_id` int(11) DEFAULT NULL,
`mod_date` timestamp NULL DEFAULT NULL,
`created_user_id` int(11) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
`rs_company_user_id` int(11) DEFAULT NULL,
`rs_base_user_id` int(11) DEFAULT NULL,
`firsttime_get_started` tinyint(1) NOT NULL DEFAULT '0',
`is_cb_migrated` tinyint(4) DEFAULT '0',
`zendesk_user_id` varchar(255) DEFAULT NULL,
`is_sync_zendesk` tinyint(4) DEFAULT '0' COMMENT '0:not sync;1:synced;2:error',
`zendesk_sync_date` timestamp NULL DEFAULT NULL,
`flag_company` int(11) DEFAULT NULL COMMENT '1:CB;2:EB;3:TR',
`merge_account_id` int(11) DEFAULT NULL,
`interact_people_uid` varchar(255) DEFAULT NULL,
`interact_people_id` varchar(255) DEFAULT NULL,
`is_sync_to_interact` tinyint(4) DEFAULT '0' COMMENT '0:not synced;1:synced;2:xml-error',
`sync_interact_date` timestamp NULL DEFAULT NULL,
`update_current_team` tinyint(1) DEFAULT '0',
`parsed_org_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `company_user_id` (`company_user_id`),
KEY `org` (`organisation_id`),
KEY `flag_company` (`flag_company`),
KEY `company_id` (`company_id`,`company_user_id`),
KEY `zendesk_user_id` (`zendesk_user_id`,`is_sync_zendesk`),
KEY `zendesk_sync_date` (`zendesk_sync_date`),
KEY `mod_date` (`mod_date`),
KEY `sync_to_interact` (`is_sync_to_interact`,`interact_people_uid`,`status`) USING BTREE,
KEY `sync_interact_date` (`sync_interact_date`,`mod_date`),
KEY `status` (`account_number`,`status`) USING BTREE,
KEY `username` (`status`,`username`(4)) USING BTREE,
KEY `rs_comp_user` (`rs_company_user_id`,`company_id`,`is_eb_migrated`),
KEY `getOrganisation` (`company_id`,`company_user_id`),
KEY `username_2` (`username`),
KEY `eb_reff_id` (`eb_reff_id`),
KEY `get_index_comp` (`company_user_id`,`is_eb_migrated`)
) ENGINE=InnoDB AUTO_INCREMENT=557225 DEFAULT CHARSET=utf8;
CREATE TABLE `company_team_users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`base_company_id` int(11) DEFAULT NULL,
`team_id` int(11) NOT NULL,
`status` int(11) DEFAULT NULL,
`start_date` datetime DEFAULT NULL,
`end_date` datetime DEFAULT NULL,
`last_mod_user_id` int(11) NOT NULL,
`mod_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_user_id` int(11) NOT NULL,
`created_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`is_cb_migrated` tinyint(4) DEFAULT '0',
`merge_account_id` int(11) DEFAULT NULL,
`is_eb_migrated` tinyint(4) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `teamID` (`team_id`),
KEY `user_id` (`user_id`),
KEY `status` (`status`),
KEY `end_date` (`end_date`),
KEY `getTeam` (`base_company_id`,`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=586851 DEFAULT CHARSET=utf8;
Try this one, move company_team_users next to the base table and use JOIN(this will short list the result based on the filter) instead of LEFT JOIN to shorten the result of the first two tables. Then remove other column filter in where clause and include it in your join.
SELECT
cs.delivery_consultant_id AS user_id,
interview.id AS interview_id,
date(interview.interview_date) AS interview_date,
date(interview.mod_date) AS interview_mod_date,
count(interview.id) AS kpi_item_count,
cu.division_id,
bu.organisation_id,
ctu.team_id
FROM es_shortlist AS cs
JOIN company_team_users AS ctu ON ctu.user_id = cs.delivery_consultant_id AND ISNULL(ctu.end_date) AND ctu.status = 2
LEFT JOIN tms_vacancies AS vac ON cs.vacancy_id = vac.id
LEFT JOIN es_applications AS app ON app.vacancy_id = vac.id AND app.candidate_id = cs.candidate_id
LEFT JOIN tms_interviews AS interview ON app.id = interview.application_id
LEFT JOIN company_users AS cu ON cu.id = cs.delivery_consultant_id
LEFT JOIN base_users AS bu ON bu.company_user_id = cs.delivery_consultant_id AND bu.company_id = cu.base_company_id
WHERE cs.delivery_consultant_id ='53521'
GROUP BY cs.delivery_consultant_id, ctu.team_id
Additional Note
Add index to those table columns that are commonly used in joins and where clause;
Ex:
es_shortlist (delivery_consultant_id)
company_team_users (user_id, end_date, status)
es_applications (vacancy_id, candidate_id)
tms_interviews (application_id)
base_users (company_user_id, company_id)

How to improve performance on this slow query?

I would like to get help to improve the indexes of this query.
SELECT DISTINCT pro_id, pro_url, pro_data, pro_capa, pro_destaque,
pro_destaque_data, pro_nome, pro_likes, pro_views,
pro_comentarios_total, pro_autor
FROM projeto
JOIN utilizador_projeto ON pro_id=utp_proid
JOIN utilizador ON utp_utiid=uti_id
WHERE pro_activo=1
AND pro_privacidade=1
ORDER BY pro_destaque_data DESC
LIMIT 24;
Here is the EXPLAIN
+------+-------------+--------------------+--------+-----------------------------------------------------------------------------------------------+---------------------+---------+---------------------------------+-------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+--------------------+--------+-----------------------------------------------------------------------------------------------+---------------------+---------+---------------------------------+-------+------------------------------+
| 1 | SIMPLE | projeto | ref | PRIMARY,pro_likes_index,pro_comments_index,pro_views_index,pro_date_index,pro_destaques_index | pro_destaques_index | 2 | const,const | 13195 | Using where; Using temporary |
| 1 | SIMPLE | utilizador_projeto | ref | utp_utiid,utp_proid | utp_proid | 4 | ic.projeto.pro_id | 1 | Distinct |
| 1 | SIMPLE | utilizador | eq_ref | PRIMARY | PRIMARY | 4 | ic.utilizador_projeto.utp_utiid | 1 | Using index; Distinct |
+------+-------------+--------------------+--------+-----------------------------------------------------------------------------------------------+---------------------+---------+---------------------------------+-------+------------------------------+
3 rows in set (0.001 sec)
and
CREATE TABLE `projeto` (
`pro_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`pro_data` int(10) unsigned NOT NULL,
`pro_url` varchar(255) DEFAULT NULL,
`pro_nome` varchar(160) DEFAULT NULL,
`pro_autor` varchar(160) DEFAULT NULL,
`pro_descricao` varchar(255) DEFAULT NULL,
`pro_projeto` longtext,
`pro_projeto_editar` longtext,
`pro_capa` varchar(255) DEFAULT NULL,
`pro_activo` tinyint(3) unsigned NOT NULL DEFAULT '0',
`pro_views` int(10) unsigned NOT NULL DEFAULT '1',
`pro_comentarios_total` int(10) unsigned NOT NULL DEFAULT '0',
`pro_comentarios` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '0 - sem comentários, 1 - com comentários',
`pro_adulto` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '0 - não é pra adultos, 1 - é pra adultos',
`pro_privacidade` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '1 - qualquer um pode ver, 2 - projeto com password, 3 - projeto secreto acessível só com link',
`pro_password` varchar(40) DEFAULT NULL,
`pro_destaque` tinyint(3) unsigned NOT NULL DEFAULT '0',
`pro_destaque_data` int(10) unsigned DEFAULT NULL,
`pro_categorias` varchar(500) DEFAULT NULL,
`pro_espacamento` smallint(5) unsigned DEFAULT '28',
`pro_espacamento_rodape` smallint(5) unsigned DEFAULT '28',
`pro_espacamento_cabecalho` smallint(5) unsigned DEFAULT '28',
`pro_background` varchar(255) DEFAULT '#FFF',
`pro_likes` int(10) unsigned NOT NULL DEFAULT '0',
`pro_coautoria` tinyint(3) unsigned DEFAULT NULL,
`pro_seguinte` varchar(255) DEFAULT NULL COMMENT 'projeto seguinte',
`pro_anterior` varchar(255) DEFAULT NULL COMMENT 'projeto anterior',
PRIMARY KEY (`pro_id`),
KEY `pro_likes_index` (`pro_activo`,`pro_privacidade`,`pro_likes`),
KEY `pro_comments_index` (`pro_activo`,`pro_privacidade`,`pro_comentarios_total`),
KEY `pro_views_index` (`pro_activo`,`pro_privacidade`,`pro_views`),
KEY `pro_date_index` (`pro_activo`,`pro_privacidade`,`pro_data`),
KEY `pro_destaques_index` (`pro_activo`,`pro_privacidade`,`pro_destaque_data`)
) ENGINE=InnoDB AUTO_INCREMENT=46247 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
CREATE TABLE `utilizador` (
`uti_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uti_tipo` tinyint(3) unsigned NOT NULL,
`uti_admin` tinyint(3) unsigned NOT NULL DEFAULT '0',
`uti_data` int(10) unsigned NOT NULL,
`uti_estado` tinyint(3) unsigned NOT NULL DEFAULT '0',
`uti_pagar` tinyint(3) unsigned DEFAULT NULL,
`uti_destaque` int(10) unsigned DEFAULT NULL,
`uti_empresa_dimensao` enum('1-10 empregados','11-50 empregados','51-200 empregados','201+ empregados') DEFAULT NULL,
`uti_empresa_verificada` tinyint(3) unsigned DEFAULT NULL,
`uti_nome` varchar(255) NOT NULL,
`uti_email` varchar(255) DEFAULT NULL,
`uti_email_equipa` varchar(255) DEFAULT NULL,
`uti_subdominio` varchar(60) DEFAULT NULL,
`uti_password` varchar(255) DEFAULT NULL,
`uti_hash` varchar(32) DEFAULT NULL,
`uti_pasid` int(10) unsigned DEFAULT NULL,
`uti_localizacao` varchar(80) DEFAULT NULL,
`uti_latitude` decimal(11,9) DEFAULT NULL,
`uti_longitude` decimal(11,9) DEFAULT NULL,
`uti_telefone` varchar(255) DEFAULT NULL,
`uti_nif` varchar(30) DEFAULT NULL,
`uti_nome_faturacao` varchar(90) DEFAULT NULL,
`uti_morada_faturacao` varchar(255) DEFAULT NULL,
`uti_codigopostal_faturacao` varchar(12) DEFAULT NULL,
`uti_cidade_faturacao` varchar(40) DEFAULT NULL,
`uti_link_faturas` varchar(255) DEFAULT NULL,
`uti_biografia` varchar(500) DEFAULT NULL,
`uti_funcao` varchar(52) DEFAULT NULL,
`uti_sexo` tinyint(3) unsigned DEFAULT NULL,
`uti_data_nascimento` date DEFAULT NULL,
`uti_website` varchar(255) DEFAULT NULL,
`uti_freelance_preco_hora` decimal(6,2) unsigned DEFAULT NULL,
`uti_freelance_preco_projeto` decimal(6,2) unsigned DEFAULT NULL,
`uti_freelance_categorias` varchar(255) DEFAULT NULL,
`uti_freelance_orcamentos` varchar(50) DEFAULT NULL,
`uti_curriculo` varchar(90) DEFAULT NULL,
`uti_ultimo_login` int(10) unsigned DEFAULT NULL,
`uti_browser` varchar(255) DEFAULT NULL,
`uti_top_competencias` varchar(1200) DEFAULT '''<li class="skill top-skill"></li><li class="skill top-skill"></li><li class="skill top-skill"></li>''',
`uti_top_projetos` varchar(3200) DEFAULT '''<li></li><li></li><li></li><li></li>''',
`uti_skills` varchar(1200) DEFAULT NULL,
`uti_seguindo` int(10) unsigned DEFAULT '0' COMMENT 'total de users que segue',
`uti_seguidores` int(10) unsigned DEFAULT '0' COMMENT 'total de seguidores',
`uti_projetos_apreciados` int(10) unsigned DEFAULT '0' COMMENT 'total de projetos apreciados',
`uti_ranking` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'ranking de pesquisas',
`uti_visitas` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'total de visitas ao perfil',
`uti_fb` varchar(255) DEFAULT NULL,
`uti_instagram` varchar(255) DEFAULT NULL,
`uti_twitter` varchar(255) DEFAULT NULL,
`uti_aviso_perfil_incompleto` tinyint(3) unsigned DEFAULT '0',
`uti_aviso_validacao` tinyint(3) unsigned DEFAULT '0',
`uti_aviso_projetos` tinyint(3) unsigned DEFAULT '0',
`uti_avaliacao_nome` varchar(20) DEFAULT NULL,
`uti_avaliacao_pontuacao` decimal(2,1) unsigned DEFAULT NULL,
`uti_avaliacao_comentarios` smallint(5) unsigned DEFAULT NULL,
PRIMARY KEY (`uti_id`),
UNIQUE KEY `uti_email` (`uti_email`),
UNIQUE KEY `uti_subdominio` (`uti_subdominio`),
KEY `uti_ranking` (`uti_ranking`),
KEY `uti_visitas` (`uti_visitas`),
KEY `uti_tipo` (`uti_tipo`),
KEY `uti_activo` (`uti_estado`),
KEY `uti_pro` (`uti_pro`),
KEY `uti_destaque` (`uti_destaque`),
KEY `uti_pasid` (`uti_pasid`),
KEY `uti_emprego_estado` (`uti_emprego_estado`),
CONSTRAINT `utilizador_ibfk_3` FOREIGN KEY (`uti_pasid`) REFERENCES `pais` (`pas_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=26880 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
CREATE TABLE `utilizador_projeto` (
`utp_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`utp_utiid` int(10) unsigned NOT NULL,
`utp_proid` int(10) unsigned NOT NULL,
`utp_posicao` int(10) unsigned NOT NULL DEFAULT '0',
`utp_admin` tinyint(3) unsigned NOT NULL DEFAULT '0',
`utp_activo` tinyint(3) unsigned NOT NULL DEFAULT '0',
`utp_equipa` tinyint(3) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`utp_id`),
KEY `utp_utiid` (`utp_utiid`),
KEY `utp_proid` (`utp_proid`),
CONSTRAINT `utilizador_projeto_ibfk_2` FOREIGN KEY (`utp_proid`) REFERENCES `projeto` (`pro_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `utilizador_projeto_ibfk_3` FOREIGN KEY (`utp_utiid`) REFERENCES `utilizador` (`uti_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=43978 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
For starters, you are not even pulling any values from your other joined tables, I would remove them right away. Next, would be the index. Having many indexes on individual columns won't necessarily help you if you are applying criteria and/ordering by multiple parts. For this query, I would have a single on
index on ( pro_activo, pro_privacidade, pro_destaque_data )
Lastly, since you are doing DISTINCT, and one of the columns is the "PRO_ID" which is the auto-increment, there would only ever be one record with that ID, so you could remove the DISTINCT clause as well leaving just
SELECT
p.pro_id,
p.pro_url,
p.pro_data,
p.pro_capa,
p.pro_destaque,
p.pro_destaque_data,
p.pro_nome,
p.pro_likes,
p.pro_views,
p.pro_comentarios_total,
p.pro_autor
FROM
projeto p
WHERE
p.pro_activo=1
AND p.pro_privacidade=1
ORDER BY
p.pro_destaque_data DESC
LIMIT 24;

mysql 'slow queries log' return a huge number of rows examined but explain seems ok

The sql query
# Query_time: 16.536276 Lock_time: 0.000159 Rows_sent: 756 Rows_examined: 8392194
SET timestamp=1555422526;
SELECT c.id AS c__id, c.company_id AS c__company_id,
c.ordinary_price AS c__ordinary_price, c.nights AS c__nights,
c.food_type AS c__food_type, c.period AS c__period,
c.period_desc AS c__period_desc, c.extra AS c__extra,
c.coupons_bought AS c__coupons_bought, c.coupon_price AS c__coupon_price,
c.coordinates AS c__coordinates, c.best_price AS c__best_price,
c.from_price AS c__from_price, c.end_datetime AS c__end_datetime,
c.hide_clock AS c__hide_clock, c.hide_discount AS c__hide_discount,
c.booking_hotel_id AS c__booking_hotel_id, c.title AS c__title,
c.option_people AS c__option_people, c.option_room AS c__option_room,
c.option_period AS c__option_period, c.city AS c__city,
c2.id AS c2__id, c2.people AS c2__people, c2.room AS c2__room,
( SELECT c8.url AS c8__url
FROM campaign_images c8
WHERE (c8.campaign_id = c.id
AND c8.photo_type = 'list')
ORDER BY c8.ordering ASC LIMIT 1
) AS c__0
FROM campaign c
LEFT JOIN campaign_options c2 ON c.id = c2.campaign_id
AND (c2.active = 1)
LEFT JOIN city_in_campaign c3 ON c.id = c3.campaign_id
LEFT JOIN city c4 ON c3.city_id = c4.id
LEFT JOIN company c5 ON c.company_id = c5.id
LEFT JOIN campaign_in_category c6 ON c.id = c6.campaign_id
LEFT JOIN campaign_in_group c7 ON c.id = c7.campaign_id
WHERE c.id IN ('13308', '13281', '13265')
AND (c.status IN ('published')
AND c.start_datetime <= NOW()
AND c.end_datetime >= NOW()
AND c5.id = '2111'
AND c.id != '14624'
AND (c7.group_id in (1)
OR c7.group_id is NULL
)
)
ORDER BY c.coupon_expire_datetime ASC;
create table campaign
CREATE TABLE `campaign` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`company_id` int(11) DEFAULT NULL,
`source_id` int(11) DEFAULT NULL,
`secondary_source_id` int(11) DEFAULT NULL,
`source_hotel_id` int(11) DEFAULT NULL,
`booking_hotel_id` int(11) DEFAULT NULL,
`booking_board_id` int(11) DEFAULT NULL,
`booking_rate` varchar(100) DEFAULT NULL,
`ordinary_price` decimal(9,2) NOT NULL,
`best_price` tinyint(1) NOT NULL DEFAULT '0',
`from_price` tinyint(1) NOT NULL DEFAULT '0',
`status` varchar(10) DEFAULT 'draft',
`type` varchar(20) DEFAULT 'other',
`deal_status` varchar(20) DEFAULT 'in_progress',
`coupon_price` decimal(9,2) NOT NULL,
`cosmote_discount` decimal(5,2) DEFAULT NULL,
`nights` int(11) NOT NULL DEFAULT '0',
`period` varchar(255) DEFAULT NULL,
`period_desc` varchar(1000) DEFAULT NULL,
`hide_period` tinyint(1) NOT NULL DEFAULT '0',
`food_type` varchar(100) DEFAULT NULL,
`stars` varchar(100) DEFAULT NULL,
`adults` tinyint(1) DEFAULT NULL,
`childs` tinyint(1) DEFAULT NULL,
`extra` varchar(255) DEFAULT NULL,
`best_point` varchar(511) DEFAULT NULL,
`extra_night_price` decimal(9,2) NOT NULL DEFAULT '0.00',
`high_season_price` decimal(9,2) NOT NULL DEFAULT '0.00',
`high_season_desc` varchar(500) DEFAULT NULL,
`high_season_extra_night_price` decimal(9,2) NOT NULL DEFAULT '0.00',
`family_packages_desc` varchar(1000) DEFAULT NULL,
`coordinates` varchar(70) DEFAULT NULL,
`start_datetime` datetime DEFAULT NULL,
`end_datetime` datetime DEFAULT NULL,
`coupon_expire_datetime` datetime DEFAULT NULL,
`active` tinyint(4) NOT NULL DEFAULT '1',
`city` varchar(255) DEFAULT NULL,
`min_coupons` int(11) NOT NULL DEFAULT '0',
`is_global` tinyint(4) NOT NULL DEFAULT '0',
`hide_clock` tinyint(1) NOT NULL DEFAULT '0',
`hide_discount` tinyint(1) NOT NULL DEFAULT '0',
`hide_purchases` tinyint(1) NOT NULL DEFAULT '0',
`booking_enabled` tinyint(1) NOT NULL DEFAULT '0',
`booking_phone` varchar(50) DEFAULT NULL,
`refresh` tinyint(1) NOT NULL DEFAULT '0',
`installments` tinyint(1) NOT NULL DEFAULT '1',
`receipt` enum('0','1') NOT NULL DEFAULT '0',
`newsletters_sent` tinyint(4) NOT NULL DEFAULT '0',
`max_coupons` int(11) NOT NULL DEFAULT '0',
`max_coupons_per_user` int(11) DEFAULT NULL,
`coupons_bought` int(11) unsigned NOT NULL DEFAULT '0',
`fake_orders` int(11) DEFAULT '0',
`title` varchar(255) DEFAULT NULL,
`newsletter_title` varchar(500) DEFAULT NULL,
`linkwise_title` varchar(500) DEFAULT NULL,
`option_title` varchar(255) DEFAULT NULL,
`option_title_en` varchar(255) DEFAULT NULL,
`option_people` varchar(150) DEFAULT NULL,
`option_room` varchar(150) DEFAULT NULL,
`option_period` varchar(150) DEFAULT NULL,
`name` varchar(1200) DEFAULT NULL,
`description` text,
`highlights` text,
`coupon_instructions` text,
`show_in_recent_deals` tinyint(4) NOT NULL DEFAULT '1',
`youtube_video_id` varchar(100) DEFAULT NULL,
`in_side` tinyint(4) NOT NULL DEFAULT '0',
`family` tinyint(1) NOT NULL DEFAULT '0',
`send_newsletter` tinyint(4) NOT NULL DEFAULT '1',
`resend_newsletter` tinyint(4) NOT NULL DEFAULT '0',
`modified_datetime` timestamp NULL DEFAULT NULL,
`created_datetime` datetime NOT NULL,
`ordering` int(11) unsigned DEFAULT '0',
PRIMARY KEY (`id`),
KEY `company_id_idx` (`company_id`),
KEY `user_id_idx` (`user_id`),
KEY `status_indx` (`status`),
KEY `str_dt_indx` (`start_datetime`),
KEY `end_dt_indx` (`end_datetime`),
KEY `side_indx` (`in_side`),
KEY `ord_indx` (`ordering`),
KEY `global_indx` (`is_global`),
KEY `act_indx` (`active`),
KEY `coup_expr_index` (`coupon_expire_datetime`)
) ENGINE=InnoDB AUTO_INCREMENT=14788 DEFAULT CHARSET=utf8
create table campaign_options
CREATE TABLE `campaign_options` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`campaign_id` int(11) NOT NULL,
`coupons_bought` int(11) unsigned NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`name_en` varchar(255) DEFAULT NULL,
`people` varchar(100) DEFAULT NULL,
`room` varchar(100) DEFAULT NULL,
`food` varchar(100) DEFAULT NULL,
`period` varchar(100) DEFAULT NULL,
`coupon_price` decimal(9,2) NOT NULL,
`extra_night_price` decimal(9,2) NOT NULL DEFAULT '0.00',
`high_season_price` decimal(9,2) DEFAULT '0.00',
`high_season_extra_night_price` decimal(9,2) NOT NULL DEFAULT '0.00',
`modified_datetime` timestamp NULL DEFAULT NULL,
`created_datetime` datetime NOT NULL,
`main` tinyint(1) NOT NULL DEFAULT '0',
`family` tinyint(1) NOT NULL DEFAULT '0',
`active` tinyint(4) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `campaign_id_idx` (`campaign_id`),
KEY `active_indx` (`active`),
KEY `family_indx` (`family`),
KEY `main_indx` (`main`)
) ENGINE=InnoDB AUTO_INCREMENT=48990 DEFAULT CHARSET=utf8
create table city_in_campaign
CREATE TABLE `city_in_campaign` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`campaign_id` int(11) DEFAULT NULL,
`city_id` int(11) DEFAULT NULL,
`ordering` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `campaign_id_idx` (`campaign_id`),
KEY `city_id_idx` (`city_id`),
KEY `order_indx` (`ordering`)
) ENGINE=InnoDB AUTO_INCREMENT=227176 DEFAULT CHARSET=utf8
create table city
CREATE TABLE `city` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`country_id` int(11) DEFAULT NULL,
`name` varchar(100) DEFAULT NULL,
`is_active` tinyint(3) unsigned DEFAULT NULL,
`modified_datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `country_id_idx` (`country_id`),
KEY `is_active_indx` (`is_active`)
) ENGINE=InnoDB AUTO_INCREMENT=254 DEFAULT CHARSET=utf8
create table company
CREATE TABLE `company` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`ref_id` int(11) DEFAULT NULL,
`name` varchar(100) DEFAULT NULL,
`description` text,
`logo` varchar(255) DEFAULT NULL,
`phone_number` varchar(100) DEFAULT NULL,
`address` varchar(200) DEFAULT NULL,
`coordinates` varchar(70) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`website` varchar(255) DEFAULT NULL,
`skype_name` varchar(50) DEFAULT NULL,
`icq_number` varchar(255) DEFAULT NULL,
`payment_information` text,
`extra1` text,
`extra2` text,
`extra3` text,
`video` varchar(500) DEFAULT NULL,
`checked` tinyint(1) NOT NULL DEFAULT '0',
`ordering` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `checked_indx` (`checked`),
KEY `ordering_indx` (`ordering`)
) ENGINE=InnoDB AUTO_INCREMENT=2519 DEFAULT CHARSET=utf8
create table campaign_in_category
CREATE TABLE `campaign_in_category` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`campaign_id` int(11) NOT NULL,
`category_id` int(11) DEFAULT NULL,
`ordering` int(11) NOT NULL DEFAULT '0',
`created_datetime` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `campaign_id_idx` (`campaign_id`),
KEY `category_id_idx` (`category_id`),
KEY `order_indx` (`ordering`)
) ENGINE=InnoDB AUTO_INCREMENT=457080 DEFAULT CHARSET=utf8
create table campaign_in_group
CREATE TABLE `campaign_in_group` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`campaign_id` int(11) DEFAULT NULL,
`group_id` int(11) DEFAULT NULL,
`created_datetime` datetime DEFAULT NULL,
`modified_datetime` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `camp_group_indx` (`campaign_id`,`group_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1175 DEFAULT CHARSET=utf8
campaign total rows: 12,657
campaign_options total rows: 43,714
city_in_campaign total rows: 15,162
city total rows: 215
company total rows: 1,756
campaign_in_category total rows: 38,817
campaign_in_group total rows: 395
explain of the query
which ones have index
it looks you need composite index because file sorting.
usage:
CREATE INDEX index_name
ON table_name(c2,c3,c4);
You are getting above result because some time o/p of explain gives different result as response of query of prod.
For optimization of query you can't have a fix answer. it varies from case to case. As for this situation I think you need to perform performance testing of this query. You can do this by inserting some records in all referenced table and then checking it's performance using explain.
LEFT JOIN campaign_in_category c6 ON c.id = c6.campaign_id
seems to be totally useless. But the Optimizer may not realize it. Remove it and any other dead code.

Indexes in Mysql table

I have such tables:
CREATE TABLE `skadate_newsfeed_action` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`entityId` int(11) NOT NULL,
`entityType` varchar(100) NOT NULL,
`feature` varchar(100) NOT NULL,
`data` longtext NOT NULL,
`status` varchar(20) NOT NULL DEFAULT 'active',
`createTime` int(11) NOT NULL,
`updateTime` int(11) NOT NULL,
`userId` int(11) NOT NULL,
`visibility` int(11) NOT NULL,
`privacy` enum('everybody','friends_only') NOT NULL DEFAULT 'everybody',
PRIMARY KEY (`id`),
KEY `userId` (`userId`),
KEY `privacy` (`visibility`),
KEY `updateTime` (`updateTime`),
KEY `entity` (`entityType`,`entityId`)
) ENGINE=MyISAM;
CREATE TABLE `skadate_profile` (
`profile_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(128) NOT NULL DEFAULT '',
`username` varchar(32) NOT NULL DEFAULT '',
`password` varchar(40) NOT NULL,
`sex` bigint(20) DEFAULT NULL,
`match_sex` bigint(20) DEFAULT NULL,
`birthdate` date NOT NULL DEFAULT '0000-00-00',
`headline` varchar(128) DEFAULT '',
`general_description` text,
`match_agerange` varchar(6) DEFAULT NULL,
`custom_location` varchar(255) DEFAULT NULL,
`country_id` char(2) NOT NULL DEFAULT '',
`zip` varchar(10) DEFAULT NULL,
`state_id` varchar(5) DEFAULT NULL,
`city_id` int(11) DEFAULT '0',
`join_stamp` int(10) unsigned NOT NULL DEFAULT '0',
`activity_stamp` int(10) unsigned NOT NULL DEFAULT '0',
`membership_type_id` int(10) unsigned NOT NULL DEFAULT '18',
`affiliate_id` int(8) unsigned NOT NULL DEFAULT '0',
`email_verified` enum('undefined','yes','no') NOT NULL DEFAULT 'undefined',
`reviewed` enum('n','y') NOT NULL DEFAULT 'n',
`has_photo` enum('n','y') NOT NULL DEFAULT 'n',
`has_media` enum('n','y') NOT NULL DEFAULT 'n',
`status` enum('active','on_hold','suspended') NOT NULL DEFAULT 'active',
`featured` enum('n','y') NOT NULL DEFAULT 'n',
`register_invite_score` tinyint(3) NOT NULL DEFAULT '0',
`rate_score` tinyint(3) unsigned NOT NULL DEFAULT '0',
`rates` bigint(20) unsigned NOT NULL DEFAULT '0',
`language_id` int(10) unsigned NOT NULL DEFAULT '0',
`join_ip` int(11) unsigned NOT NULL DEFAULT '0',
`neigh_location` enum('country','state','city','zip') DEFAULT NULL,
`neigh_location_distance` int(10) unsigned NOT NULL DEFAULT '0',
`bg_color` varchar(32) DEFAULT NULL,
`bg_image` varchar(32) DEFAULT NULL,
`bg_image_url` varchar(255) DEFAULT NULL,
`bg_image_mode` tinyint(1) DEFAULT NULL,
`bg_image_status` enum('active','approval') NOT NULL DEFAULT 'active',
`has_music` enum('n','y') NOT NULL DEFAULT 'n',
`is_private` tinyint(1) NOT NULL DEFAULT '0',
`subscription_id_offerit` text,
PRIMARY KEY (`profile_id`),
UNIQUE KEY `email` (`email`),
UNIQUE KEY `username` (`username`),
KEY `membership_id` (`membership_type_id`),
KEY `zip` (`zip`),
KEY `country_id` (`country_id`),
KEY `state_id` (`state_id`),
KEY `city_id` (`city_id`),
KEY `sex` (`sex`),
KEY `match_sex` (`match_sex`),
KEY `activity_stamp` (`activity_stamp`),
KEY `join_stamp` (`join_stamp`),
KEY `birthdate` (`birthdate`),
KEY `featured` (`featured`,`has_photo`,`activity_stamp`)
) ENGINE=MyISAM;
And try to perform this query:
SELECT DISTINCT `na`.*
FROM `skadate_newsfeed_action` AS `na`
LEFT JOIN `skadate_profile` AS `profile` ON ( `na`.`userId` = `profile`.`profile_id` )
WHERE ( profile.email_verified='yes' OR profile.email_verified='no' OR profile.email_verified='undefined' )
AND `profile`.`status`='active' AND `na`.`status`='active' AND `na`.`privacy`='everybody'
AND `na`.`visibility` & 1 AND `na`.`updateTime` < 1455885224
ORDER BY `na`.`updateTime` DESC, `na`.`id` DESC
LIMIT 0, 10
But when I see EXPLAIN:
Maybe someone can help me, how I can improve this query?
If you want records from only one table, then use exists rather than a join and select distinct. So:
SELECT na.*
FROM `skadate_newsfeed_action` na
WHERE EXISTS (SELECT 1
FROM skadate_profile p
WHERE na.userId = p.profile_id AND
p.email_verified IN ('yes', 'no', 'undefined') AND
p.status = 'active'
) AND
na.status = 'active' AND
na.privacy = 'everybody' AND
na.visibility & 1 > 0 AND
na.updateTime < 1455885224
ORDER BY na.`updateTime` DESC, na.`id` DESC
LIMIT 0, 10;
For this query, you want an index on skadate_profile(profile_id, status, verified). Also, the following index is probably helpful: skadate_newsfeed_action(status, privacy, updateTime, visibility, userId).
This is probably because of the DISTICT keyword. To remove duplicates MySQL needs to sort the result by every selected column.

My query is not using my indexes, how do i use explain plan and fix this slow query with MySQL

I have this query that is running slow (16 seconds), it only has 44085 records in the biggest table. Any suggestions or anything that sticks out?
thanks for any help
SELECT u.`vid`, u.`userID`, u.`localConID`, u.`lastran`, u.`laststatus`,
u.`lastmessage`, u.`active`
,u.`autorundaily`, u.`autorunmonthly`, u.`fileslocation`
,c.`conid`, c.`fname`, c.`lname`, c.`homephone`, c.`cellphone` , c.`email` ,
DATE_FORMAT(u.`lastran`,'%d/%m/%y %k:%i') lastranFormatted, u.`retrys`
FROM virtual_alerts_users u
LEFT JOIN virtual_alerts_cons c ON c.referid = u.localConID
WHERE u.userID = 9581
When i do an explain i get::
id | select_type | table | type | possible_keys | key | key_len | ref | rows | extra
1 | SIMPLE | u | ALL | Index 3 | null | null | null | 459 | Using where
1 | SIMPLE | c | ALL | null | null | null | null | 44085 |
The tables look like::
CREATE TABLE `virtual_alerts_users` (
`vid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`userID` INT(11) NOT NULL DEFAULT '0',
`localConID` VARCHAR(10) NULL DEFAULT NULL,
`encrpytPW` VARCHAR(100) NULL DEFAULT NULL,
`lastran` TIMESTAMP NULL DEFAULT NULL,
`laststatus` INT(11) NULL DEFAULT NULL,
`lastmessage` TEXT NULL,
`active` TINYINT(4) NOT NULL DEFAULT '0',
`autorundaily` TINYINT(4) NOT NULL DEFAULT '0',
`autorunmonthly` TINYINT(4) NOT NULL DEFAULT '0',
`fileslocation` VARCHAR(512) NULL DEFAULT NULL,
`retrys` TINYINT(4) NULL DEFAULT '0',
PRIMARY KEY (`vid`),
UNIQUE INDEX `Index 2` (`localConID`),
INDEX `Index 3` (`userID`)
)
-
CREATE TABLE `virtual_alerts_cons` (
`conid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`userID` INT(11) UNSIGNED NOT NULL DEFAULT '0',
`vid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
`fname` VARCHAR(50) NULL DEFAULT NULL,
`lname` VARCHAR(50) NULL DEFAULT NULL,
`referid` VARCHAR(10) NULL DEFAULT NULL,
`level` VARCHAR(2) NULL DEFAULT NULL,
`status` VARCHAR(2) NULL DEFAULT NULL,
`lang` VARCHAR(15) NULL DEFAULT NULL,
`homephone` VARCHAR(15) NULL DEFAULT NULL,
`cellphone` VARCHAR(15) NULL DEFAULT NULL,
`address` VARCHAR(255) NULL DEFAULT NULL,
`email` VARCHAR(255) NULL DEFAULT NULL,
`birthday_mon` TINYINT(4) NULL DEFAULT '0',
`birthday_day` TINYINT(4) NULL DEFAULT '0',
`anv_mon` TINYINT(4) NULL DEFAULT '0',
`anv_day` TINYINT(4) NULL DEFAULT '0',
`anv_cnt` TINYINT(4) NULL DEFAULT '0',
`lasthash` BIGINT(20) NULL DEFAULT '0',
`lastupdated` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`conid`),
UNIQUE INDEX `Index 3` (`userID`, `referid`),
INDEX `Index 2` (`userID`),
INDEX `Index 4` (`vid`)
)
You have no index on referid in virtual_alerts_cons, but you do have a combined index on userID and referid.
To force MySQL to use that, change your join condition to:
LEFT JOIN
virtual_alerts_cons c
ON
c.referid = u.localConID
AND
c.userId = u.userID
Alternatively, you could create an additional index on referid.
The table virtual_alerts_con doesn't have the right kind of index for referid.
CREATE TABLE `virtual_alerts_cons` (
`conid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`userID` INT(11) UNSIGNED NOT NULL DEFAULT '0',
`vid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
`fname` VARCHAR(50) NULL DEFAULT NULL,
`lname` VARCHAR(50) NULL DEFAULT NULL,
`referid` VARCHAR(10) NULL DEFAULT NULL,
`level` VARCHAR(2) NULL DEFAULT NULL,
`status` VARCHAR(2) NULL DEFAULT NULL,
`lang` VARCHAR(15) NULL DEFAULT NULL,
`homephone` VARCHAR(15) NULL DEFAULT NULL,
`cellphone` VARCHAR(15) NULL DEFAULT NULL,
`address` VARCHAR(255) NULL DEFAULT NULL,
`email` VARCHAR(255) NULL DEFAULT NULL,
`birthday_mon` TINYINT(4) NULL DEFAULT '0',
`birthday_day` TINYINT(4) NULL DEFAULT '0',
`anv_mon` TINYINT(4) NULL DEFAULT '0',
`anv_day` TINYINT(4) NULL DEFAULT '0',
`anv_cnt` TINYINT(4) NULL DEFAULT '0',
`lasthash` BIGINT(20) NULL DEFAULT '0',
`lastupdated` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`conid`),
UNIQUE INDEX `Index 3` (`userID`, `referid`),
INDEX `Index 2` (`userID`),
INDEX `Index 5` (`referid`),
INDEX `Index 4` (`vid`)
)
You can also probably change the query to something like this
SELECT u.`vid`, u.`userID`, u.`localConID`, u.`lastran`, u.`laststatus`,
u.`lastmessage`, u.`active`
,u.`autorundaily`, u.`autorunmonthly`, u.`fileslocation`
,c.`conid`, c.`fname`, c.`lname`, c.`homephone`, c.`cellphone` , c.`email` ,
DATE_FORMAT(u.`lastran`,'%d/%m/%y %k:%i') lastranFormatted, u.`retrys`
FROM virtual_alerts_users u
LEFT JOIN virtual_alerts_cons c ON c.referid = u.localConID AND c.userId = 9581
WHERE u.userID = 9581
That will probably take advantage of the Index 3 with both userId and referid.
The explain plan shows you that it is scanning all the rows of the virtual_alerts_con table because it can't use any indexes. Your "Index 3" isn't helping because its a multi-column index. There are restrictions on how you use multi-column indexes.
If you have an index with A, B, C, you can't search on just column C. You can search with just A, or A+B, or A+B+C.