mySQL 查询随机执行需要很长时间

mySQL query Randomly takes a long time to execute

我是查询优化的新手,所以我已经阅读了很多文章并观看了 YouTube 等内容,但我仍然无法弄明白。

问题是我想为 API 执行此查询:

SELECT  req_id,follow_requests.insta_id as id,caption,follow_requests.male,
        users.name,users.profile_pic
    FROM  follow_requests
    INNER JOIN  users  ON follow_requests.insta_id = users.insta_id
    WHERE  (remaining_follow>0 && req_id<='574989')
      AND  NOT EXISTS
    (
        SELECT  *
            FROM  follows
            WHERE  follows.req_id=follow_requests.req_id
              AND  follows.follower_insta_id='3134816134'
    )
    ORDER BY  req_id DESC
    LIMIT  20

所以我记录了我的数据库,摘要显示这个正在占用我 +42% 的资源 此查询的某些实例看起来像 300 秒,平均为 20 秒!(他们卡在发送数据状态) 所以我试着把它改得更好(不是我真的知道我在做什么 :) 我把它改成了这个

SELECT  fr.req_id, fr.insta_id as id, fr.caption, fr.male, u.name,
        u.profile_pic, fr.date, fr.remaining_follow
    FROM  follow_requests AS fr
    INNER JOIN  users AS u  ON fr.insta_id=u.insta_id
    WHERE  fr.remaining_follow>0
      AND  fr.insta_id!=3134816134
      AND  NOT EXISTS 
    (
        SELECT  *
            FROM  follows as f
            WHERE  f.req_id=fr.req_id
              AND  f.follower_insta_id='3134816134'
    )
    ORDER BY  fr.date DESC
    LIMIT  20

奇怪的是,前几次运行还可以!像从 0.1 秒到 0.7 秒 在试运行中 但是在我稍微伸展一下然后回来完成它之后,这也停留了 +200,300 秒但是这次在排序状态 我用 explain 检查了查询,发现它没有使用日期索引! 如果我只从查询中删除 'order by' 部分,它就会变得非常快 ~0.2s

有什么想法吗?

顺便说一句,几乎所有的列都被索引了,并且跟随 table 有 2M 行其他有 +100k

抱歉,如果我不能很好地解释它或者我错过了给你一些重要的信息,我是新手 ;)

如果您能以新手可以理解的方式解释它,同时又不会遗漏重要细节,我将不胜感激:)

提前致谢

=-=-=-=-=-=-= 更新1 =-=-=-=-=-=-=

感谢您的帮助,我现在找到了这个查询,虽然省时但 我不得不稍微改变一下整个事情,但它可能仍然有问题

SELECT  follow_requests.req_id, follow_requests.insta_id as id,
        caption, follow_requests.male, users.name,users.profile_pic
    FROM  follow_requests
    INNER JOIN  users  ON follow_requests.insta_id = users.insta_id
    LEFT OUTER JOIN  follows  ON follows.req_id = follow_requests.req_id
      AND  follows.follower_insta_id = '3134816134'
    WHERE  follow_requests.remaining_follow >0
      AND  follow_requests.insta_id != 3134816134
      AND  (follows.follower_insta_id != 3134816134 || follows.follower_insta_id is null)
    ORDER BY  follow_requests.date DESC
    LIMIT  20

嗯,首先我要说的是我没有写原始查询(第一个)而且我自己也不理解所有的内容:/但是主程序员现在是遥不可及的,我必须代替他否则整个项目将失败

关于这个问题,每个人都可以为 insta_id 提交多个请求,但应该只 return 其中一个 主要代码和@Kickstart 代码(这是原始代码的优化版本,平均响应时间约为 10 秒)是否正确(出于某种原因我不明白 但是我的代码 returns 相同 insta_id 的多个实例(具有不同的 req_id)

还有人能告诉我为什么第一个查询表现如此糟糕吗?

我得到了 2 个解决方案

第一名:

而不是使用 "select *" 使用 "select id"

SELECT fr.req_id, fr.insta_id as id, fr.caption, fr.male, u.name, u.profile_pic, fr.date, fr.remaining_follow
FROM follow_requests AS fr INNER JOIN users AS u 
ON fr.insta_id=u.insta_id
WHERE fr.remaining_follow>0 AND fr.insta_id!=3134816134 
    AND NOT EXISTS (SELECT f.id FROM follows as f WHERE f.req_id=fr.req_id AND f.follower_insta_id='3134816134')
ORDER BY fr.date DESC LIMIT 20

2ND:

你可以的

SELECT fr.req_id, 
       fr.insta_id AS id, 
       fr.caption, 
       fr.male, 
       u.name, 
       u.profile_pic, 
       fr.date, 
       fr.remaining_follow 
FROM   follow_requests AS fr 
       INNER JOIN users AS u 
               ON fr.insta_id = u.insta_id 
       INNER JOIN follows AS f 
              ON f.req_id = fr.req_id 
                 AND f.follower_insta_id != '3134816134' 
WHERE  fr.remaining_follow > 0 
       AND fr.insta_id != 3134816134
ORDER  BY fr.date DESC 
LIMIT  20 

确实需要查看 table 声明和查询的 EXPLAIN。

然而,可能值得尝试以下 table 的 LEFT OUTER JOIN,并检查是否匹配(通过检查必须在 table 上填充的列是否为 NULL) .

但是,您是否有包含 req_id 和 follower_insta_id 字段的以下 table 的索引?不是 2 个单独的索引,而是一个涵盖两个领域的索引。

SELECT req_id,
        follow_requests.insta_id as id,
        caption,
        follow_requests.male,
        users.name,users.profile_pic 
FROM follow_requests 
INNER JOIN users ON follow_requests.insta_id = users.insta_id 
LEFT OUTER JOIN follows ON follows.req_id = follow_requests.req_id AND follows.follower_insta_id = '3134816134'
WHERE follows.req_id IS NULL
AND remaining_follow > 0 
AND req_id <= '574989'
ORDER BY req_id DESC 
LIMIT 20