SQLite mit Index?

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

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
Grüßle.
Benutzeravatar
lutz.horn
User
Beiträge: 205
Registriert: Dienstag 8. November 2005, 12:57
Wohnort: Pforzheim

Welchen Index hast Du wie angelegt?

Welches SQLite-Python-Modul verwendest Du?

Wo wird die Zeit verbraucht: in fetchall() oder in index()?
https://www.xing.com/go/invite/18513630.6a91d4
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

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.)
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

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
Grüßle.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

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.
Bottle: Micro Web Framework + Development Blog
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

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
Grüßle.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

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
Antworten