Mysql 如何缩短此SQL查询的时间

Mysql 如何缩短此SQL查询的时间,mysql,sql,optimization,query-optimization,Mysql,Sql,Optimization,Query Optimization,有人能告诉我如何减少使用此查询的时间吗 这是SQL查询: SELECT `i`.`id`, `i`.`local_file`, `i`.`remote_file`, `i`.`remote_file_big`, `i`.`image_name`, `i`.`description`, IF(`i`.`prevent_sync`='1', '5', `i`.`status`) `status`, GROUP_CONCA

有人能告诉我如何减少使用此查询的时间吗

这是SQL查询:

SELECT 
    `i`.`id`, 
    `i`.`local_file`, 
    `i`.`remote_file`, 
    `i`.`remote_file_big`, 
    `i`.`image_name`, 
    `i`.`description`,
     IF(`i`.`prevent_sync`='1', '5', `i`.`status`) `status`,
     GROUP_CONCAT(`il`.`user_id` SEPARATOR ',') AS `likes`,
     COUNT(`il`.`user_id`) AS `likes_count`
FROM `images` `i`
LEFT JOIN `image_likes` `il` ON (`il`.`image_id`=`i`.`id`) 
WHERE 1 AND `i`.`created` < DATE_SUB(CURDATE(), INTERVAL 48 HOUR) 
GROUP BY `i`.`id` 
ORDER BY `likes_count` DESC LIMIT 3 OFFSET 0;
表格图像\u喜欢:


请提出建议。

对于DB来说,这是一项复杂的任务,要真正有效地获得结果,您所能做的并不多。您可以尝试使用对覆盖索引进行操作的子查询来限制IO。从查询中删除不需要获取三个图像ID的所有内容:

SELECT i.id
FROM images i
JOIN image_likes il ON il.image_id = i.id
WHERE i.created < DATE_SUB(CURDATE(), INTERVAL 48 HOUR)
GROUP BY i.id
ORDER BY COUNT(il.image_id) DESC
LIMIT 3 OFFSET 0

如果速度不够快,您应该使用触发器缓存likes\u计数。

这可能会患上膨胀-放气综合征,这在JOIN+GROUP BY中经常发生。此外,它通常会导致不正确的聚合值

SELECT  `id`, `local_file`, `remote_file`,
        `remote_file_big`, `image_name`, `description`,
        IF(`prevent_sync`='1', '5', `status`) `status`,
        s.likes, s.likes_count
    FROM  `images` AS `i`
    JOIN  
        ( SELECT  GROUP_CONCAT(user_id SEPARATOR ',') AS likes,
                  COUNT(*) AS likes_count
              FROM     `image_likes`
              GROUP BY  image_id 
              ORDER BY  `likes_count` DESC
              LIMIT  3 OFFSET 0;
        ) AS s  ON s.`image_id`=`i`.`id`
    WHERE  `created` < CURDATE() - INTERVAL 2 DAY
    ORDER BY  `likes_count` DESC;
这个变量将排除likes_count=0的行,但这似乎是合理的

它假定图像的主键是id

image_like需要INDEXuser_id,并将对该表进行一次扫描。然后只需对图像进行3次查找


原始查询必须扫描所有的图像行,并重复扫描所有的图像类。

您有索引吗?您应该在createdPost上添加索引表结构和放入的索引,并列出表结构和索引;发布查询的解释,以显示查询的执行方式显示创建表图像\u喜欢;然后把结果贴在这里。重要的是要知道,它是否在image_id字段上有索引。其中1和-这是什么?不需要1。
SELECT i.id
FROM images i
JOIN image_likes il ON il.image_id = i.id
WHERE i.created < DATE_SUB(CURDATE(), INTERVAL 48 HOUR)
GROUP BY i.id
ORDER BY COUNT(il.image_id) DESC
LIMIT 3 OFFSET 0
SELECT
    `i`.`id`, 
    `i`.`local_file`, 
    `i`.`remote_file`, 
    `i`.`remote_file_big`, 
    `i`.`image_name`, 
    `i`.`description`,
     IF(`i`.`prevent_sync`='1', '5', `i`.`status`) `status`,
     GROUP_CONCAT(`il`.`user_id` SEPARATOR ',') AS `likes`,
     COUNT(`il`.`user_id`) AS `likes_count`
FROM (
    SELECT i.id
    FROM images i
    JOIN image_likes il ON il.image_id = i.id
    WHERE i.created < DATE_SUB(CURDATE(), INTERVAL 48 HOUR)
    GROUP BY i.id
    ORDER BY COUNT(il.image_id) DESC
    LIMIT 3 OFFSET 0
) sub
JOIN images i ON i.id = sub.id
JOIN image_likes il ON il.image_id = i.id
GROUP BY i.id
ORDER BY likes_count;
SELECT  `id`, `local_file`, `remote_file`,
        `remote_file_big`, `image_name`, `description`,
        IF(`prevent_sync`='1', '5', `status`) `status`,
        s.likes, s.likes_count
    FROM  `images` AS `i`
    JOIN  
        ( SELECT  GROUP_CONCAT(user_id SEPARATOR ',') AS likes,
                  COUNT(*) AS likes_count
              FROM     `image_likes`
              GROUP BY  image_id 
              ORDER BY  `likes_count` DESC
              LIMIT  3 OFFSET 0;
        ) AS s  ON s.`image_id`=`i`.`id`
    WHERE  `created` < CURDATE() - INTERVAL 2 DAY
    ORDER BY  `likes_count` DESC;