使用 LEFT JOIN 优化 MySql 查询

标签 mysql query-optimization

我有一个需要优化的 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 = 0on 子句移至 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 放在它所属的位置将减少数据量并提高查询性能。

关于使用 LEFT JOIN 优化 MySql 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29195828/

相关文章:

php - 无法使用 PHP 更新 MySQL 中的表

mysql - MySQL 中的 LEFT OUTER JOIN 与 SUBSELECT

MySQL 将 IN 替换为 EXISTS,编辑后的查询开销更大

mysql - 如何优化低性能的MySQL查询

mysql - 在表中有一对 friend ,如何创建一个抽象获取用户 friend 列表的 View ?

php - 三元运算符变量和mysql?

mysql - SQL获取即将到来的生日的问题

php - 免费结果集数据 mysqli_result::free

mysql - MySQL 中何时使用单引号、双引号和反引号

mongodb - 针对不同的排序过滤条件应该创建哪些MongoDB索引来提高性能?