perf: SQL LIKE query instead of Python loop; skip warmup if cache >1000
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 7s

This commit is contained in:
vrubel 2026-06-20 09:06:11 +00:00
parent 34dc8b7ac6
commit 07b016bff9

View file

@ -525,28 +525,27 @@ def scan_for_player(fide_id: int, max_tnr: int = None,
results = [] results = []
seen_tnrs = set() seen_tnrs = set()
# Phase 1: check tnr_cache (instant SQL, no HTTP). Return immediately if found. # Phase 1: check tnr_cache via SQL (single query, instant). Return if found.
for cluster_lo, cluster_hi in [(1434000, 1450000)]:
conn = _get_conn() conn = _get_conn()
cached_tnrs = [ pattern = f'%"{fide_id}"%'
r[0] for r in conn.execute( rows = conn.execute(
'SELECT tnr FROM tnr_cache WHERE tnr >= ? AND tnr <= ? ORDER BY tnr DESC', 'SELECT tnr, name, start_date, end_date, players_json FROM tnr_cache '
(cluster_lo, cluster_hi)).fetchall() 'WHERE tnr >= ? AND tnr <= ? AND players_json LIKE ? '
] 'ORDER BY tnr DESC',
(1434000, 1450000, pattern)).fetchall()
conn.close() conn.close()
for tnr in cached_tnrs: for row in rows:
cdata = _get_cached_tnr(tnr) tnr, tname, tstart, tend, players_json = row
if cdata is None: players = {int(k): v for k, v in json.loads(players_json).items()}
continue player_info = players.get(fide_id)
player_info = cdata['players'].get(fide_id)
if player_info is None: if player_info is None:
continue continue
results.append({ results.append({
'tnr': tnr, 'tnr': tnr,
'url': f'https://chess-results.com/tnr{tnr}.aspx?lan=11', 'url': f'https://chess-results.com/tnr{tnr}.aspx?lan=11',
'name': cdata['name'] or f'Tournament {tnr}', 'name': tname or f'Tournament {tnr}',
'start_date': cdata['start_date'], 'start_date': tstart,
'end_date': cdata['end_date'], 'end_date': tend,
'sno': player_info['sno'], 'sno': player_info['sno'],
'player_name': player_info['name'], 'player_name': player_info['name'],
'fide_id': fide_id, 'fide_id': fide_id,
@ -634,10 +633,16 @@ async def warmup_cache(context):
"""Build full tnr_cache index (runs once at startup, then every 6h).""" """Build full tnr_cache index (runs once at startup, then every 6h)."""
import asyncio, sys, traceback import asyncio, sys, traceback
# Skip if warmup already completed # Skip if warmup already completed or cache already populated
status = get_tnr_state('warmup_tnr', '') status = get_tnr_state('warmup_tnr', '')
if status == 'done': if status == 'done':
return return
conn = _get_conn()
cache_count = conn.execute('SELECT COUNT(*) FROM tnr_cache').fetchone()[0]
conn.close()
if cache_count > 1000:
set_tnr_state('warmup_tnr', 'done')
return
print('warmup_cache: starting cluster scan (step=1, 1445000→1434000)...', file=sys.stderr) print('warmup_cache: starting cluster scan (step=1, 1445000→1434000)...', file=sys.stderr)
try: try: