]> git.rm.cloudns.org Git - xonotic/xonstat.git/commitdiff
Speed up weaponstats requests by 2.5x.
authorAnt Zucaro <azucaro@gmail.com>
Wed, 24 Dec 2014 21:55:17 +0000 (16:55 -0500)
committerAnt Zucaro <azucaro@gmail.com>
Wed, 24 Dec 2014 21:55:17 +0000 (16:55 -0500)
We can exploit the GIN index on games.players to quickly get a list of the most
recently-played games. We construct this list as a subquery that can be used in
an IN list in the main weaponstats query, greatly reducing the time needed to
fetch the rows. It's about 2.5 times faster according to apache bench.
Additionally this query is helped by moving it to a subquery, whereas once it
was two queries (thus two round trips to the DB).

xonstat/views/player.py

index b38fcf2b7e02678c760b640e71b56e301a4a7cbc..8569e0c6446108688366b1f61caf125ffb878078 100644 (file)
@@ -1076,7 +1076,7 @@ def player_captimes_json(request):
 
 
 def player_weaponstats_data_json(request):
-    player_id = request.matchdict["id"]
+    player_id = int(request.matchdict["id"])
     if player_id <= 2:
         player_id = -1;
 
@@ -1093,18 +1093,21 @@ def player_weaponstats_data_json(request):
         if limit > 50:
             limit = 50
 
-    games_raw = DBSession.query(sa.distinct(Game.game_id)).\
-        filter(Game.game_id == PlayerWeaponStat.game_id).\
-        filter(PlayerWeaponStat.player_id == player_id)
+
+    # the game_ids of the most recently played ones 
+    # of the given game type is used for a subquery
+    games_list = DBSession.query(Game.game_id).\
+            filter(Game.players.contains([player_id]))
 
     if game_type_cd is not None:
-        games_raw = games_raw.filter(Game.game_type_cd == game_type_cd)
+        games_list = games_list.filter(Game.game_type_cd == game_type_cd)
 
-    games_raw = games_raw.order_by(Game.game_id.desc()).limit(limit).all()
+    games_list = games_list.order_by(Game.game_id.desc()).limit(limit)
 
     weapon_stats_raw = DBSession.query(PlayerWeaponStat).\
         filter(PlayerWeaponStat.player_id == player_id).\
-        filter(PlayerWeaponStat.game_id.in_(games_raw)).all()
+        filter(PlayerWeaponStat.game_id.in_(games_list)).\
+        all()
 
     games_to_weapons = {}
     weapons_used = {}