[英]MySql Query Optimization with LEFT JOIN
我有一个优化的MySQL查询,因为运行此查询时,它将MySQL进程的CPU使用率提高到100%。 因此,我对该查询做了一些修改,现在它减少了其运行时间,但CPU使用率仍接近100%。 我在两个表中都索引了所有搜索字段。
这些“ milestone_and_events”和“ milestone_and_events_reminders”具有一对多的关系(“ milestone_and_events”具有一个或多个“ milestone_and_events_reminders”),并且“ milestone_and_events_reminders”表具有近150万条记录。
有什么办法可以进一步优化此查询,任何人都可以给我一个指南吗? 谢谢
这是原始查询
SELECT MAE.*
, MAER.reminder_user_id
, MAER.reminder_type
, MAER.id as reminder_id
FROM milestone_and_events AS MAE
LEFT
JOIN milestone_and_events_reminders MAER
ON MAE.id = MAER.milestone_and_events_id
WHERE MAER.alert_time < '$currentTime'
AND MAER.issued ! = 1
AND MAE.completed = 0
GROUP
BY MAE.id
, MAER.reminder_user_id
, MAER.reminder_type
这是我目前的查询
$currentTime = date('Y-m-d H:i:s');
$query = 'SELECT MAE.id, MAE.time, MAER.reminder_user_id, MAER.reminder_type, MAER.id AS reminder_id
FROM milestone_and_events AS MAE
LEFT JOIN milestone_and_events_reminders MAER ON
MAE.id = MAER.milestone_and_events_id AND
MAER.issued =0 AND
MAER.alert_time < "' . $currentTime . '" AND
MAE.completed =0
WHERE MAER.reminder_type != "onTime"
GROUP BY MAER.milestone_and_events_id,MAER.reminder_user_id,MAER.reminder_type';
更新1
此“ milestone_and_events”表具有近200个条目。
CREATE TABLE `milestone_and_events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`description` varchar(250) NOT NULL,
`time` datetime NOT NULL,
`attached_type` int(11) DEFAULT NULL,
`attached_type_value` int(11) DEFAULT NULL,
`completed` int(11) NOT NULL DEFAULT '0',
`type` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `time` (`time`),
KEY `completed` (`completed`),
KEY `id` (`id`,`completed`)
) ENGINE=InnoDB AUTO_INCREMENT=154 DEFAULT CHARSET=utf8
“ milestone_and_events_reminders”表具有近150万个条目。
CREATE TABLE `milestone_and_events_reminders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`reminder_user_id` int(11) NOT NULL,
`milestone_and_events_id` int(11) NOT NULL,
`alert_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`issued` tinyint(11) NOT NULL DEFAULT '0',
`reminder_type` enum('upComming','delayed','onTime') NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`reminder_user_id`),
KEY `reminder_type` (`reminder_type`),
KEY `issued` (`issued`),
KEY `milestone_and_events_id` (`milestone_and_events_id`, `issued`,`reminder_type`),
CONSTRAINT `milestone_and_events_reminders_ibfk_1` FOREIGN KEY (`milestone_and_events_id`)
REFERENCES `milestone_and_events` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=3323544 DEFAULT CHARSET=utf8
这是您的查询:
SELECT MAE.id, MAE.time, MAER.reminder_user_id, MAER.reminder_type, MAER.id AS reminder_id
FROM milestone_and_events AS MAE LEFT JOIN
milestone_and_events_reminders MAER
ON MAE.id = MAER.milestone_and_events_id AND
MAER.issued = 0 AND
MAER.alert_time < "' . $currentTime . '"
WHERE MAE.completed = 0 AND MAER.reminder_type <> "onTime"
GROUP BY MAE.id, MAER.reminder_user_id, MAER.reminder_type;
注意:我将条件MAE.completed = 0
从on
子句移到了where
子句。 它在on
子句中什么也不做。 而且,我更改了group by
的第一个键以匹配SELECT
。
此查询的最佳索引是复合索引: milestone_and_events(completed, id)
和milestone_and_events_reminders(milestone_and_events_id, issued, alert_time, reminder_type)
。
我的猜测是,将completed = 0
放在其所属的位置将减少数据量并提高查询的性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.