Skip to content

Commit 9bbe870

Browse files
committed
chore: performance indexes
1 parent a5b69f8 commit 9bbe870

5 files changed

Lines changed: 88 additions & 69 deletions

File tree

hasura/functions/players/get_player_matches.sql

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,27 @@ BEGIN
1111
END;
1212
$$;
1313

14-
CREATE OR REPLACE FUNCTION public.get_total_player_matches(player public.players) RETURNS INT
15-
LANGUAGE plpgsql STABLE
16-
AS $$
17-
DECLARE
18-
total_matches INT;
19-
BEGIN
20-
SELECT COUNT(DISTINCT m.id)
21-
INTO total_matches
22-
FROM match_lineup_players mlp
23-
INNER JOIN matches m ON (m.lineup_1_id = mlp.match_lineup_id OR m.lineup_2_id = mlp.match_lineup_id)
24-
WHERE mlp.steam_id = player.steam_id;
14+
CREATE OR REPLACE FUNCTION public.get_total_player_matches(player players)
15+
RETURNS integer
16+
LANGUAGE sql
17+
STABLE
18+
AS $$
19+
SELECT COUNT(DISTINCT id)
20+
FROM (
21+
SELECT m.id
22+
FROM match_lineup_players mlp
23+
JOIN matches m
24+
ON m.lineup_1_id = mlp.match_lineup_id
25+
WHERE mlp.steam_id = player.steam_id
2526

26-
RETURN total_matches;
27-
END;
27+
UNION ALL
28+
29+
SELECT m.id
30+
FROM match_lineup_players mlp
31+
JOIN matches m
32+
ON m.lineup_2_id = mlp.match_lineup_id
33+
WHERE mlp.steam_id = player.steam_id
34+
) s;
2835
$$;
2936

3037
CREATE OR REPLACE FUNCTION public.get_total_player_wins(player public.players) RETURNS INT
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
CREATE INDEX IF NOT EXISTS idx_player_elo_steam_id_type_created_at
2+
ON player_elo(steam_id, type, created_at DESC);
3+
4+
CREATE INDEX IF NOT EXISTS idx_match_lineup_players_steam_id_lineup_id
5+
ON match_lineup_players(steam_id, match_lineup_id);
6+
7+
-- Partial index for active matches only
8+
CREATE INDEX IF NOT EXISTS idx_matches_status_lineup
9+
ON matches(status, lineup_1_id, lineup_2_id)
10+
WHERE status IN ('Live', 'Veto');
11+
12+
CREATE INDEX IF NOT EXISTS idx_match_options_id_type
13+
ON match_options(id) INCLUDE (type);
14+
15+
CREATE INDEX IF NOT EXISTS idx_matches_lineup_ids
16+
ON matches(lineup_1_id, lineup_2_id)
17+
INCLUDE (id, match_options_id, winning_lineup_id, created_at);
18+
19+
CREATE INDEX IF NOT EXISTS idx_matches_match_options_id
20+
ON matches(match_options_id);

hasura/views/v_player_elo.sql

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,17 @@
11
DROP VIEW IF EXISTS v_player_elo;
22

3-
4-
-- Create a view that shows ELO changes for each match for each player
53
CREATE OR REPLACE VIEW v_player_elo AS
6-
WITH match_player_elo_data AS (
7-
SELECT
8-
m.id AS match_id,
9-
mo."type" AS "type",
10-
m.created_at AS match_created_at,
11-
p.steam_id AS player_steam_id,
12-
p.name AS player_name,
13-
CASE
14-
WHEN m.winning_lineup_id = mlp.match_lineup_id THEN 'win'
15-
ELSE 'loss'
16-
END AS match_result,
17-
get_elo_for_match(m.id, p.steam_id) AS elo_data
18-
FROM
19-
matches m
20-
JOIN
21-
match_lineup_players mlp ON (mlp.match_lineup_id = m.lineup_1_id OR mlp.match_lineup_id = m.lineup_2_id)
22-
JOIN
23-
players p ON p.steam_id = mlp.steam_id
24-
JOIN
25-
match_options mo ON mo.id = m.match_options_id
26-
)
274
SELECT
28-
match_id,
29-
"type",
30-
match_created_at,
31-
player_steam_id,
32-
player_name,
33-
match_result,
5+
m.id AS match_id,
6+
mo."type" AS "type",
7+
m.created_at AS match_created_at,
8+
p.steam_id AS player_steam_id,
9+
p.name AS player_name,
10+
CASE
11+
WHEN m.winning_lineup_id = mlp.match_lineup_id THEN 'win'
12+
ELSE 'loss'
13+
END AS match_result,
14+
-- Extract ELO data using LATERAL join for better performance
3415
(elo_data->>'current_elo')::INTEGER + (elo_data->>'elo_change')::INTEGER AS updated_elo,
3516
(elo_data->>'current_elo')::INTEGER AS current_elo,
3617
(elo_data->>'elo_change')::INTEGER AS elo_change,
@@ -48,4 +29,12 @@ SELECT
4829
(elo_data->>'damage_percent')::FLOAT AS damage_percent,
4930
(elo_data->>'performance_multiplier')::FLOAT AS performance_multiplier
5031
FROM
51-
match_player_elo_data;
32+
matches m
33+
JOIN
34+
match_lineup_players mlp ON (mlp.match_lineup_id = m.lineup_1_id OR mlp.match_lineup_id = m.lineup_2_id)
35+
JOIN
36+
players p ON p.steam_id = mlp.steam_id
37+
JOIN
38+
match_options mo ON mo.id = m.match_options_id
39+
CROSS JOIN LATERAL
40+
get_elo_for_match(m.id, p.steam_id) AS elo_data;

src/matchmaking/matchmaking-lobby.service.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -162,23 +162,32 @@ export class MatchmakingLobbyService {
162162
}>;
163163
},
164164
) {
165-
const _players = [];
166-
for (const { steam_id } of lobby.players) {
167-
const { players_by_pk } = await this.hasura.query({
168-
players_by_pk: {
169-
__args: {
170-
steam_id,
171-
},
172-
elo: true,
165+
166+
const { players } = await this.hasura.query({
167+
players: {
168+
__args: {
169+
where: {
170+
steam_id: { _in: lobby.players.map(p => p.steam_id) }
171+
}
173172
},
174-
});
173+
steam_id: true,
174+
elo: true,
175+
},
176+
});
175177

178+
const eloMap = new Map(
179+
players.map(p => [p.steam_id, p.elo])
180+
);
181+
182+
// Build player list using the map
183+
const _players = lobby.players.map(({ steam_id }) => {
184+
const playerElo = eloMap.get(steam_id);
176185
let elo = 5000;
177-
if (players_by_pk?.elo) {
178-
elo = Number(players_by_pk.elo[type.toLowerCase()]);
186+
if (playerElo) {
187+
elo = Number(playerElo[type.toLowerCase()]);
179188
}
180-
_players.push({ steam_id, rank: elo });
181-
}
189+
return { steam_id, rank: elo };
190+
});
182191

183192
const matchmakingLobby: MatchmakingLobby = {
184193
type,

src/type-sense/type-sense.service.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -207,15 +207,9 @@ export class TypeSenseService {
207207
last_sign_in_at: true,
208208
wins: true,
209209
losses: true,
210-
kills_aggregate: {
211-
aggregate: {
212-
count: true,
213-
},
214-
},
215-
deaths_aggregate: {
216-
aggregate: {
217-
count: true,
218-
},
210+
stats: {
211+
kills: true,
212+
deaths: true,
219213
},
220214
sanctions_aggregate: {
221215
aggregate: {
@@ -287,11 +281,11 @@ export class TypeSenseService {
287281
Object.assign({}, player, elo, {
288282
id: steamId,
289283
steam_id: steamId,
290-
kills: player.kills_aggregate?.aggregate?.count
291-
? parseInt(String(player.kills_aggregate?.aggregate?.count), 10)
284+
kills: player.stats?.kills
285+
? parseInt(String(player.stats.kills), 10)
292286
: 0,
293-
deaths: player.deaths_aggregate?.aggregate?.count
294-
? parseInt(String(player.deaths_aggregate?.aggregate?.count), 10)
287+
deaths: player.stats?.deaths
288+
? parseInt(String(player.stats.deaths), 10)
295289
: 0,
296290
wins: player.wins ? parseInt(String(player.wins), 10) : 0,
297291
losses: player.losses ? parseInt(String(player.losses), 10) : 0,

0 commit comments

Comments
 (0)