【问题标题】:Hi I have written a following mysql query but its taking too much of my cpu.how can I optimizie it嗨,我写了一个以下 mysql 查询,但它占用了我的 cpu 太多。我该如何优化它
【发布时间】:2018-11-01 17:22:37
【问题描述】:
set @points := -1;
set @c := 1;
set @num := 0;
SELECT `player_id`,`name`,`firebase_token`,`highscore`,`fb_pic_url`,`profile_pic`
          , @num := if(@points = `highscore`, @num, @num + @c) as rank
          , @c := if(@points = `highscore`, @c+1, 1) as dummy
          , @points := `highscore` as dummy2
        FROM 
        (SELECT  `Match_History`.`player_id`,`players`.`name`,`players`.`firebase_token`,`players`.`profile_pic`,`players`.`fb_pic_url`,`Match_History`.`highscore`
            FROM `Match_History`,`players`
            WHERE (`Match_History`.`player_id`,`Match_History`.`highscore`) IN 
            ( 
              SELECT `player_id`, MAX(`highscore`)
              FROM `Match_History`
              WHERE `contest_id`=128
              GROUP BY `player_id`
            ) 
            AND `Match_History`.`player_id`=`players`.`id`
                GROUP BY `players`.`id`
            ORDER BY `Match_History`.`highscore` DESC ,`Match_History`.`timestamp`
        ) t 
        ORDER BY `highscore` desc, `player_id` asc;

我正在使用上面的 mysql 查询从下面提到的表中创建排行榜:

Match_History

idint(11) 非空,

player_id int(11) 非空,

contest_id int(11) 非空,

highscore int(11) 非空,

timestamptimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP

玩家:

id int(11) 非空, name varchar(100) 默认为空,

profile_picvarchar(30) 默认为空,

fb_pic_urlvarchar(150) 默认为空,

firebase_tokenvarchar(500) 默认为空,

timestamptimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP

以上查询占用过多 CPU,我想对其进行优化。 我非常努力,但无法找到正确的方法来以更优化的方式获得相同的结果。 有人可以帮我吗?

【问题讨论】:

  • 你不能使用连接吗?
  • 使用 EXPLAIN 查看查询的潜在问题可能在哪里。
  • 在DB接口或带入PHP时占用资源过多?
  • 什么是解释,对不起,我不太擅长 mysql,但我正在努力改进。有人可以帮助我在这里如何使用 JOIN。根据我的研究,使用连接可以优化它
  • 仅在数据库中执行需要一段时间

标签: mysql


【解决方案1】:

这是使用连接的第一个技巧:

SELECT  `Match_History`.`player_id`,`players`.`name`,`players`.`firebase_token`,`players`.`profile_pic`,`players`.`fb_pic_url`,`Match_History`.`highscore`
FROM `Match_History` MH 
JOIN `players` P on MH.player_id = P.id
JOIN  ( 
  SELECT `player_id`, MAX(`highscore`)
  FROM `Match_History`
  WHERE `contest_id`=128
  GROUP BY `player_id`
) HS on HS.player_id = MH.player_id and HS.highscore = MH.highscore
GROUP BY `players`.`id`
ORDER BY `Match_History`.`highscore` DESC ,`Match_History`.`timestamp`

确保执行良好,然后在执行时添加剩余的逻辑。

在查询前添加EXPLAIN 可以查看查询计划。

我会补充一点,如果它使用大量 CPU,那么您很可能缺少索引,并且花费时间扫描内存页面(表扫描)。确保所有连接列和 where 子句中的所有列都有适当的索引。

【讨论】:

  • 嗨,谢谢您引导我走上正确的道路,您的查询中有一些错误我已修复,现在我的查询优化了 10 倍。
  • SELECT id,player_id,name,firebase_token,highscore , @num := if(@points = highscore, @num, @num + @c) as rank , @c := if( @points = highscore, @c+1, 1) as dummy , @points := (highscore) as dummy2 from ( SELECT Match_History.id,player_id,name,firebase_token,max(@ 987654329@) as highscore,fb_pic_url,profile_pic FROM Match_History LEFT JOIN player ON Match_History.player_id = player.id where Competition_id=1501 GROUP by player_id ORDER BY highscore DESC) t
猜你喜欢
  • 2017-07-25
  • 2011-01-30
  • 1970-01-01
  • 2012-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 2022-01-06
相关资源
最近更新 更多