... ON leaderboard (score)
並べ替え操作を避けるために、 index を追加することをお勧めします。また、不要な SELECT を UPDATE ステートメントから削除することをお勧めします (ただし、それがパフォーマンスに影響するかどうかはわかりませんが、そのコンテキストでは SELECT キーワードは必要ありません。
ソート操作は確かにいくらかの CPU を使用します。UPDATE ステートメント内の SELECT がオプティマイザーによって無視されるのか、それとも計画がそこにある (不要な?) SELECT と何らかの形で異なるのかは、私には明らかではありません。(そのコンテキストに SELECT キーワードを含める目的は何ですか?)
また、リーダーボード テーブルのすべての行でロックを取得するために、すべての行からスコア値を返す必要はありません。その SELECT ステートメントの ORDER BY も CPU サイクルを消費している可能性があります (score
先行列としてのインデックスがない場合)。4M 行の結果セットの不要な準備も CPU サイクルを消費しています。
UPDATE ステートメント自体が必要なロックを取得するときに、SELECT ... FOR UPDATE を使用して、テーブル内のすべての行のロックを取得する必要がある理由は明らかではありません。(SELECT ... FOR UPDATE ステートメントは、BEGIN TRANSACTION のコンテキストでのみ、または自動コミットが無効になっている場合にのみロックを取得します。(ここでleaderboard
は、それが InnoDB テーブルであると想定しています。)
MySQL は、並べ替え操作を回避するためにインデックスを利用できる場合があります。
CREATE INDEX leaderboard_IX1 ON leaderboard (score) ;
そして、これはランク列を更新するのに十分なはずです:
SET @rankCounter := 0;
UPDATE leaderboard
SET rank = @rankCounter := @rankCounter + 1
ORDER BY score DESC ;