refactor(live-state): drop redundant ix_sps_server_recent index

The two indexes ix_sps_server_open and ix_sps_server_recent were
byte-identical because SQLAlchemy's Index(name, *cols) form drops the
DESC ordering the spec intended. Rather than reach for text("left_at
DESC"), drop the second index entirely — SQLite scans the ASC index
backwards at no measurable cost. Spec and plan updated to match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mwiegand 2026-05-12 21:27:01 +02:00
parent 0f825686c6
commit e25e7098f6
No known key found for this signature in database
4 changed files with 1 additions and 8 deletions

View file

@ -194,7 +194,6 @@ class ServerPlayerSession(Base):
__tablename__ = "server_player_session" __tablename__ = "server_player_session"
__table_args__ = ( __table_args__ = (
Index("ix_sps_server_open", "server_id", "left_at"), Index("ix_sps_server_open", "server_id", "left_at"),
Index("ix_sps_server_recent", "server_id", "left_at"),
Index("ix_sps_steam_history", "steam_id_64", "joined_at"), Index("ix_sps_steam_history", "steam_id_64", "joined_at"),
{"sqlite_autoincrement": True}, {"sqlite_autoincrement": True},
) )
@ -311,7 +310,6 @@ def upgrade() -> None:
sqlite_autoincrement=True, sqlite_autoincrement=True,
) )
op.create_index("ix_sps_server_open", "server_player_session", ["server_id", "left_at"]) op.create_index("ix_sps_server_open", "server_player_session", ["server_id", "left_at"])
op.create_index("ix_sps_server_recent", "server_player_session", ["server_id", "left_at"])
op.create_index( op.create_index(
"ix_sps_steam_history", "server_player_session", ["steam_id_64", "joined_at"] "ix_sps_steam_history", "server_player_session", ["steam_id_64", "joined_at"]
) )
@ -329,7 +327,6 @@ def upgrade() -> None:
def downgrade() -> None: def downgrade() -> None:
op.drop_table("steam_user_profile") op.drop_table("steam_user_profile")
op.drop_index("ix_sps_steam_history", table_name="server_player_session") op.drop_index("ix_sps_steam_history", table_name="server_player_session")
op.drop_index("ix_sps_server_recent", table_name="server_player_session")
op.drop_index("ix_sps_server_open", table_name="server_player_session") op.drop_index("ix_sps_server_open", table_name="server_player_session")
op.drop_table("server_player_session") op.drop_table("server_player_session")
op.drop_index("ix_sls_server_started", table_name="server_live_state") op.drop_index("ix_sls_server_started", table_name="server_live_state")

View file

@ -99,8 +99,7 @@ CREATE TABLE server_player_session (
max_ping INTEGER NOT NULL max_ping INTEGER NOT NULL
); );
CREATE INDEX ix_sps_server_open ON server_player_session(server_id, left_at); CREATE INDEX ix_sps_server_open ON server_player_session(server_id, left_at);
CREATE INDEX ix_sps_server_recent ON server_player_session(server_id, left_at DESC); CREATE INDEX ix_sps_steam_history ON server_player_session(steam_id_64, joined_at);
CREATE INDEX ix_sps_steam_history ON server_player_session(steam_id_64, joined_at DESC);
``` ```
- `joined_at` is **backfilled from RCON's `connected` duration** on first sighting (`joined_at = now - connected_seconds`). This heals brief polling gaps and survives web restarts: even if we just started polling, we know when the still-connected players actually joined. - `joined_at` is **backfilled from RCON's `connected` duration** on first sighting (`joined_at = now - connected_seconds`). This heals brief polling gaps and survives web restarts: even if we just started polling, we know when the still-connected players actually joined.

View file

@ -84,7 +84,6 @@ def upgrade() -> None:
sqlite_autoincrement=True, sqlite_autoincrement=True,
) )
op.create_index("ix_sps_server_open", "server_player_session", ["server_id", "left_at"]) op.create_index("ix_sps_server_open", "server_player_session", ["server_id", "left_at"])
op.create_index("ix_sps_server_recent", "server_player_session", ["server_id", "left_at"])
op.create_index( op.create_index(
"ix_sps_steam_history", "server_player_session", ["steam_id_64", "joined_at"] "ix_sps_steam_history", "server_player_session", ["steam_id_64", "joined_at"]
) )
@ -102,7 +101,6 @@ def upgrade() -> None:
def downgrade() -> None: def downgrade() -> None:
op.drop_table("steam_user_profile") op.drop_table("steam_user_profile")
op.drop_index("ix_sps_steam_history", table_name="server_player_session") op.drop_index("ix_sps_steam_history", table_name="server_player_session")
op.drop_index("ix_sps_server_recent", table_name="server_player_session")
op.drop_index("ix_sps_server_open", table_name="server_player_session") op.drop_index("ix_sps_server_open", table_name="server_player_session")
op.drop_table("server_player_session") op.drop_table("server_player_session")
op.drop_index("ix_sls_server_started", table_name="server_live_state") op.drop_index("ix_sls_server_started", table_name="server_live_state")

View file

@ -201,7 +201,6 @@ class ServerPlayerSession(Base):
__tablename__ = "server_player_session" __tablename__ = "server_player_session"
__table_args__ = ( __table_args__ = (
Index("ix_sps_server_open", "server_id", "left_at"), Index("ix_sps_server_open", "server_id", "left_at"),
Index("ix_sps_server_recent", "server_id", "left_at"),
Index("ix_sps_steam_history", "steam_id_64", "joined_at"), Index("ix_sps_steam_history", "steam_id_64", "joined_at"),
{"sqlite_autoincrement": True}, {"sqlite_autoincrement": True},
) )