Seite 1 von 1

SQLite mit Index?

Verfasst: Samstag 11. Juli 2009, 16:23
von theliquidwave
Hi.
Ich erstelle derzeit für ein Onlinegame ein Rankingsystem welches nach Kills sortiert ist. Das heißt, der Spieler mit den meisten Kills ist Erster.
Die Tabelle ist so aufgebaut:

Code: Alles auswählen

playerid VARCHAR      username VARCHAR      kills INTEGER      deaths INTEGER
Bei Google habe ich folgendes über Indizen gefunden: http://sql.1keydata.com/de/sql-create-index.php

Meine Frage ist nun, ob mir das überhaupt was bringt, denn das Problem ist, dass ich die Position des Ranks ermitteln muss. Ich kann dank SQL zwar schnell ermitteln, wie viele Kills der jeweilige Spieler hat, dennoch habe ich bisher immer wiefolgt die Position ermittelt:

Code: Alles auswählen

database.query("SELECT playerid FROM ranks WHERE kills > 49 ORDER BY kills DESC, tode ASC, username ASC")
position = database.cursor.fetchall().index((playerid,)) + 1
Das ganze funktioniert zwar relativ gut, dennoch dauert es umso länger, desto weiter hinten der Spieler im Ranking ist.

Ich weiß derzeit nicht so wirklich, ob ich mit dem Index was anfangen kann, oder wie man das am besten lösen kann.

~ Chris

Verfasst: Montag 13. Juli 2009, 07:16
von lutz.horn
Welchen Index hast Du wie angelegt?

Welches SQLite-Python-Modul verwendest Du?

Wo wird die Zeit verbraucht: in fetchall() oder in index()?

Verfasst: Montag 13. Juli 2009, 08:33
von ms4py
Versuch es mal damit (SQL-Anweisung ganz unten):
http://www.sqlteam.com/article/returnin ... in-a-query

Dann kannst du auch mit `WHERE player_id=?` im SQL die Position von einem Spieler generieren.

(Vielleicht die SELECT noch als View erstellen, ist dann vielleicht optimierter, wenn du öfters auf die Position von einem bestimmten Spieler zugreifen willst.)

Verfasst: Montag 13. Juli 2009, 13:39
von theliquidwave
Hi.
@ lutz: Ich habe momentan noch keinen Index angelegt, da es momentan nichts bringen würde. Ich benutze die dbapi2 ("from sqlite3 import dbapi2 as sqlite"). Das Problem ist ja nicht, alle Einträge zu bekommen, sondern sie dann mit .index zu durchsuchen. Wenn der Spieler der gesucht wird z.B. auf Rank 10.000 ist, so werden 10.000 Einträge mit .index durchsucht, bevor man zu einem Ergebnis kommt.

@ ice: Ich versteh nicht so ganz? Wie meinst du das mit "`WHERE player_id=?`"? Wie kann ich denn damit die Position bestimmen?

Danke an euch beide!

~ Chris

Verfasst: Montag 13. Juli 2009, 13:49
von Defnull
Versuchs in zwei Schritten:

Erst "SELECT kills, tode, username FROM ranks WHERE playerid={playerid}" um die Leistungen des Spielers heraus zu finden und dann:

Code: Alles auswählen

SELECT count(*)
FROM ranks
WHERE kills > {kills}
   OR (kills = {kills} AND tode < {tode})
   OR (kills = {kills} AND tode = {tode} AND username < {username})")
um zu zählen, wie viele Leute besser sind als der gesuchte Spieler.

Verfasst: Montag 13. Juli 2009, 15:02
von theliquidwave
GEIL!!!
Das geht wunderbar und ist viel schneller als das mit .index.
Vielen Dank!

EDIT: Ich hab noch eine Frage.
Ist es möglich, die Daten ausm SELECT direkt zu verarbeiten? Also dass man nur einen Query benutzt?

~ Chris

Verfasst: Montag 13. Juli 2009, 20:56
von ms4py
Indem du die Query, von dem ich den Link geschrieben habe, auf dein Problem anwendest:

Code: Alles auswählen

SELECT r.player_id,
(SELECT COUNT(*) FROM ranks r2 WHERE r2.kills > r.kills
   OR (r2.kills = r.kills AND r2.tode < r.tode)
   OR (r2.kills = r.kills AND r2.tode = r.tode AND r2.username < r.username)) AS position
FROM ranks r
ORDER BY kills DESC, tode ASC, username ASC