首页 > 解决方案 > JOIN 查询需要很长时间并创建问题“将 HEAP 转换为 MyISAM

问题描述

我的查询如下。这里我使用连接查询来获取数据。你能建议我如何解决“将 HEAP 转换为 MyISAM”的问题。 在此处输入图像描述 在此处输入图像描述

我可以在这里使用子查询来更新它吗?请建议我该怎么做。

在这里,我加入了 users 表来检查用户是否存在。我可以在不加入的情况下对其进行改进,以便“将 HEAP 转换为 MyISAM”可以解决。

哦,有时我不会检查特定的 user_id。像这里我添加了 user_id = 16082

SELECT `user_point_logs`.`id`, 
   `user_point_logs`.`user_id`, 
   `user_point_logs`.`point_get_id`, 
   `user_point_logs`.`point`, 
   `user_point_logs`.`expire_date`, 
   `user_point_logs`.`point`  AS `sum_point`, 

   IF(sum(`user_point_used_logs`.`point`) IS NULL, 0, sum(`user_point_used_logs`.`point`)) AS `minus` 

   FROM   `user_point_logs` 

     JOIN `users` ON ( `users`.`id` = `user_point_logs`.`user_id` ) 

     LEFT JOIN (SELECT * 
              FROM   user_point_used_logs 
              WHERE  user_point_log_id NOT IN (
                                                     SELECT DISTINCT return_id 
                                               FROM   user_point_logs 
                                               WHERE  return_id IS NOT NULL 
                                                      AND user_id = 16082
                                                              )
                  ) 
    AS user_point_used_logs
      ON ( `user_point_logs`.`id` = `user_point_used_logs`.`user_point_log_used_id` ) 

    WHERE  expire_date >= 1563980400 

   AND `user_point_logs`.`point` >= 0 

   AND `users`.`id` IS NOT NULL 

   AND ( `user_point_logs`.`return_id` = 0 
          OR `user_point_logs`.`return_id` IS NULL ) 

   AND `user_point_logs`.`user_id` = '16082' 

   GROUP  BY `user_point_logs`.`id` 
   ORDER  BY `user_point_logs`.`expire_date` ASC 

DB FIDDLE 结构

错误图像

标签: mysqljoinsubquerymyisam

解决方案


索引:

user_point_logs:  (user_id, expire_date)
user_point_logs:  (user_id, return_id)

OR很难优化。决定只用一种方式来表达这里所说的一切,然后去掉OR:

   AND (     `user_point_logs`.`return_id` = 0 
          OR `user_point_logs`.`return_id` IS NULL ) 

DISTINCT是多余的:

NOT IN ( SELECT DISTINCT ... )

改变

IF(sum(`user_point_used_logs`.`point`) IS NULL, 0,
   sum(`user_point_used_logs`.`point`)) AS `minus`

COALESCE( ( SELECT SUM(point) FROM   user_point_used_logs ... ), 0)  AS minus

和折腾LEFT JOIN (SELECT * FROM user_point_used_logs ... )

由于 aPRIMARY KEY是一个键,其中第二个是多余的,可以是DROPped

ADD PRIMARY KEY (`id`),
ADD KEY `id` (`id`) USING BTREE;

毕竟,我们可能需要另一遍来进一步简化和优化它。


推荐阅读