Tach,
ich hab mal bei mysql.com gelesen, dass man Select Where anfragen erheblich beschleunigen kann mit sogenannten indexen!
Hab das aber ehrlich gesagt nicht verstanden! gibts hier jmd der mir das verständlich machen kann?
grz
SaIG
Select Where ... beschleunigen
gepostet vor 18 Jahre, 11 Monate von saig
gepostet vor 18 Jahre, 11 Monate von Fornax
Das ist, wenn du "SELECT name FROM tabelle WHERE id=1" machst. Dabei muss in der DB-Struktur id als index definiert sein.
"CREATE TABLE tabelle (
`id` INT( 2 ) NOT NULL ,
PRIMARY KEY ( `id` )
)"
"CREATE TABLE tabelle (
`id` INT( 2 ) NOT NULL ,
PRIMARY KEY ( `id` )
)"
gepostet vor 18 Jahre, 11 Monate von Kampfhoernchen
Ich fang mal ganz ganz vorne an:
Normalerweise speichert MySQL seine Daten in Tabellen, die ähnlich wie CVS aufgebaut sind, in etwa so:
TABLE spieler:
spieler_id name passwort
1 mein_name asdf
2 dein_name foo
3 sein_name bar
....
TABLE planet:
planet_id name besitzer_id
1 Mein_plani 1
2 sein_plani 3
3 mein2plani 1
4 dein_plani 2
...
Soweit sollte ja klar sein.
Jetzt willst du also die Daten des Spielers 2 laden, also "SELECT * FROM spieler WHERE spieler_id = 2".
MySQL durchsucht nun die ganze Tabelle (an die Profis: Bitte weiterlesen). Sprich, die Datei wird komplett gelesen und dann durchsucht (vereinfacht ausgedrückt).
Jetzt legst du einen Index auf das Feld "spieler_id" an. Dieser wird in einer eigenen Datei gespeichert und enthält nur die "spieler_id" sowie einen Zeiger, an welcher Stelle der Haupt-Tabellen-Datei der Datensatz des entsprechenden Spielers anfängt.
Dadurch ist die Datenmenge, die MySQL durchsuchen muss, viel geringer, und die Abfrage geht dadurch schneller.
Gleichzeit muss natürlich beim Einfügen eines Datensatzes zusätzlich noch ein Eintrag in die Index-Datei gemacht werden, gleiches gilt natürlich beim manipulieren. Da das Verhältnis von SELECT zu UPDATE/INSERT/REPLACE/DELETE bei Browsergames aber Erfahrungsgemäß bei 5:1 liegt, gewinnst du dadurch trotzdem an Performance.
Da sehr oft nach den Primär-Schlüsseln gesucht wird, legt MySQL für Primärschlüssel automatisch einen Index an.
Wenn du nun aber die Planeten des Spielers laden willst, ist die spieler_id in der Planeten-Tabelle nun aber kein Primärschlüssel, sondern es ist die ID des Planeten bzw. seine Koordinaten.
Die Id des Besitzer ist dann ein sogenannter Fremdschlüssel (FOREIGN KEY), da er sich ja auf die spieler_id der Spieler Tabelle bezieht. Eine Query könnte also so aussehen:
SELECT * FROM planet WHERE besitzer = 2;
Jetzt müsste MySQL wieder die ganze Tabelle durchsuchen. Außer: Du legst einen Index auf den Fremdschlüssel an.
Technisch kannst du das recht einfach über phpmyadmin machen, indem du in der Strukturansicht einer Tabelle in der Spalte, in der du einen Index anlegen willst, auf klickst.
Die Frage, wo sich ein Index rentiert, kann man pauschal nicht sagen. Grundsätzlich sollte man jedoch alle Fremdschlüssel mit einem Index belegen. Bei Feldern, nach denen häufig sortiert wird oder die recht häufig in WHERE-Klauseln auftachen (z.B. Datum im Nachrichtensystem) wäre es auszuprobieren. Ein Index ist recht schnell angelegt und wieder gelöscht (löschen kannst du Indices auf der Strukturseite von phpmyadmin etwas weiter unten), ist also immer nen Versuch wert. Indices über Primärschlüssel lassen sich logischerweise nicht löschen.
Normalerweise speichert MySQL seine Daten in Tabellen, die ähnlich wie CVS aufgebaut sind, in etwa so:
TABLE spieler:
spieler_id name passwort
1 mein_name asdf
2 dein_name foo
3 sein_name bar
....
TABLE planet:
planet_id name besitzer_id
1 Mein_plani 1
2 sein_plani 3
3 mein2plani 1
4 dein_plani 2
...
Soweit sollte ja klar sein.
Jetzt willst du also die Daten des Spielers 2 laden, also "SELECT * FROM spieler WHERE spieler_id = 2".
MySQL durchsucht nun die ganze Tabelle (an die Profis: Bitte weiterlesen). Sprich, die Datei wird komplett gelesen und dann durchsucht (vereinfacht ausgedrückt).
Jetzt legst du einen Index auf das Feld "spieler_id" an. Dieser wird in einer eigenen Datei gespeichert und enthält nur die "spieler_id" sowie einen Zeiger, an welcher Stelle der Haupt-Tabellen-Datei der Datensatz des entsprechenden Spielers anfängt.
Dadurch ist die Datenmenge, die MySQL durchsuchen muss, viel geringer, und die Abfrage geht dadurch schneller.
Gleichzeit muss natürlich beim Einfügen eines Datensatzes zusätzlich noch ein Eintrag in die Index-Datei gemacht werden, gleiches gilt natürlich beim manipulieren. Da das Verhältnis von SELECT zu UPDATE/INSERT/REPLACE/DELETE bei Browsergames aber Erfahrungsgemäß bei 5:1 liegt, gewinnst du dadurch trotzdem an Performance.
Da sehr oft nach den Primär-Schlüsseln gesucht wird, legt MySQL für Primärschlüssel automatisch einen Index an.
Wenn du nun aber die Planeten des Spielers laden willst, ist die spieler_id in der Planeten-Tabelle nun aber kein Primärschlüssel, sondern es ist die ID des Planeten bzw. seine Koordinaten.
Die Id des Besitzer ist dann ein sogenannter Fremdschlüssel (FOREIGN KEY), da er sich ja auf die spieler_id der Spieler Tabelle bezieht. Eine Query könnte also so aussehen:
SELECT * FROM planet WHERE besitzer = 2;
Jetzt müsste MySQL wieder die ganze Tabelle durchsuchen. Außer: Du legst einen Index auf den Fremdschlüssel an.
Technisch kannst du das recht einfach über phpmyadmin machen, indem du in der Strukturansicht einer Tabelle in der Spalte, in der du einen Index anlegen willst, auf klickst.
Die Frage, wo sich ein Index rentiert, kann man pauschal nicht sagen. Grundsätzlich sollte man jedoch alle Fremdschlüssel mit einem Index belegen. Bei Feldern, nach denen häufig sortiert wird oder die recht häufig in WHERE-Klauseln auftachen (z.B. Datum im Nachrichtensystem) wäre es auszuprobieren. Ein Index ist recht schnell angelegt und wieder gelöscht (löschen kannst du Indices auf der Strukturseite von phpmyadmin etwas weiter unten), ist also immer nen Versuch wert. Indices über Primärschlüssel lassen sich logischerweise nicht löschen.
gepostet vor 18 Jahre, 11 Monate von saig
oh danke hat mir sehr weitergeholfen!
nur eins noch am querry selbst muss ich nichts ändern oder?
nur eins noch am querry selbst muss ich nichts ändern oder?
gepostet vor 18 Jahre, 11 Monate von Klaus
nö, und danke an Kampfhoernchen für die ausführliche Erklärung. Über MySQL kann man nie genug lernen.
gepostet vor 18 Jahre, 11 Monate von Kampfhoernchen
Ich muss mir dieses Zeugs 6 Doppelstunden die Woche anhören. Nennt sich "Datenbanken und Informationsmanagement"
gepostet vor 18 Jahre, 11 Monate von Nuky
das kommt bei mir erst im 3ten semester
gepostet vor 18 Jahre, 11 Monate von poncho
Nochmal kurz angeschnitten, was wichtig ist:
Jeder Datensatz sollte ein eineindeutiges Attribut haben, denn so kann die DB sicher sein, dass kein weiterer Datensatz mit diesem Wert vorhanden ist und kann so die Suche schneller beenden.
Außerdem sollte der Datentyp dieses Atrributs so klein wie möglich gewählt werden, denn so muss die DB weniger Daten verarbeiten. Das Schlimmste wäre ein Index als Text, denn da muss zeichen für Zeichen durchsucht werden.
Außerdem sollte man darauf achten, dass keine redundanten Daten vorhanden sind. So etwas verstopft die Datenbank und kann zu Inkonsistenzen führen, was im schlimmsten Fall mit dem Totalausfall endet.
Die Geschwindigkeitsvorteile sind gravierend. Ich war mal gezwungen ohne Index zu arbeiten und da hat eine simple Abfrage über zwei Tabellen mit ~20000 Datensätzen schon geschlagene 3 Sekunden gedauert.
Jeder Datensatz sollte ein eineindeutiges Attribut haben, denn so kann die DB sicher sein, dass kein weiterer Datensatz mit diesem Wert vorhanden ist und kann so die Suche schneller beenden.
Außerdem sollte der Datentyp dieses Atrributs so klein wie möglich gewählt werden, denn so muss die DB weniger Daten verarbeiten. Das Schlimmste wäre ein Index als Text, denn da muss zeichen für Zeichen durchsucht werden.
Außerdem sollte man darauf achten, dass keine redundanten Daten vorhanden sind. So etwas verstopft die Datenbank und kann zu Inkonsistenzen führen, was im schlimmsten Fall mit dem Totalausfall endet.
Die Geschwindigkeitsvorteile sind gravierend. Ich war mal gezwungen ohne Index zu arbeiten und da hat eine simple Abfrage über zwei Tabellen mit ~20000 Datensätzen schon geschlagene 3 Sekunden gedauert.