PHP/MySQL Abfrage beschleunigen
Markus Bodmann
- datenbank
Hallo,
ich kenne mich nicht so gut mit MySQL aus und eine Abfrage ide ich geschrieben habe nimmt sehr viel Zeit in Anspruch, ich schätze mal das es auch eine bessere möglichkeit gibt.
Also ich habe eine Tabelle (t1_cod4_v3_players_sd) in dieser gibt es die Spalten players_id und players_key. Jede id und jeder key sind einmalig.
In der zweiten Tabelle (t1_cod4_v3_nicks) sind zu den keys nicks gespeichert und die Anzahl wie oft welcher nick von welchem key benutz wurde (count).
Mein Ziel ist es alle keys auszugeben, mit dem Nick, der am häufigsten benutzt wurde und das ganze dann Alphabetisch nach den Nicks geordnet.
Hier ist meine Bisherige Lösung:
mysql_query("
CREATE TEMPORARY TABLE playerlist (
id bigint(10),
nick varchar(255)
);
");
$abfrage_player = mysql_query("
SELECT
t1_cod4_v3_players_sd.players_id,
t1_cod4_v3_players_sd.players_key
FROM
t1_cod4_v3_players_sd
");
while($row_player = mysql_fetch_array($abfrage_player)){
$abfrage_nick = mysql_query
("
SELECT
t1_cod4_v3_nicks.nicks_nicks
FROM
t1_cod4_v3_nicks
WHERE
t1_cod4_v3_nicks.nicks_key = '$row_player[1]'
ORDER BY
t1_cod4_v3_nicks.nicks_count DESC
LIMIT 1
");
$row_nick = mysql_fetch_array($abfrage_nick);
mysql_query("
INSERT INTO
playerlist(id, nick)
VALUES
('$row_player[0]','$row_nick[0]');
");
}
$abfrage = mysql_query
("
SELECT
*
FROM
playerlist
ORDER BY
nick ASC
");
while($row = mysql_fetch_array($abfrage)){
echo $row[0].' - '.$row[1].'<br />';
}
Hello,
SELECT
t1_cod4_v3_players_sd.players_id,
t1_cod4_v3_players_sd.players_key
FROM
t1_cod4_v3_players_sd
SELECT
t1_cod4_v3_nicks.nicks_nicks
FROM
t1_cod4_v3_nicks
WHERE
t1_cod4_v3_nicks.nicks_key = '$row_player[1]'
ORDER BY
t1_cod4_v3_nicks.nicks_count DESC
LIMIT 1
Schritt 1:
Beschäftige dich mit dem Thema Joins, d.h. nutze einen INNER JOIN zwischen den beiden Tabellen auf Basis des keys um aus diesen beiden Abfragen eine zu machen. Das erspart dir schonmal die zigfachen Abfragen.
INSERT INTO
playerlist(id, nick)
VALUES
('$row_player[0]','$row_nick[0]');
");
Schritt 2:
Wenn du das Ergebnis der ersten (zwei) Abfragen eigentlich gar nichts brauchst, dann füge nicht zeilenweise ein sondern füge direkt das Ergebnise des Selects ein
INSERT INTO playerlist
(id, nick)
SELECT id, nick
FROM <hier der Rest der ersten (zwei) Abfragen>
MfG
Rouven
Hallo,
ich kenne mich nicht so gut mit MySQL aus
das sieht man ;-) Du setzt in aufwendigem PHP in einer Schleife teure SQL-Statements ab, statt die Möglichkeiten von SQL zu nutzen: Joins und Unterabfragen.
und eine Abfrage ide
ja, wenn es nur eine wäre. Es sind viele.
ich geschrieben habe nimmt sehr viel Zeit in Anspruch, ich schätze mal das es auch eine bessere möglichkeit gibt.
Ja, gibt es. Diese wurde hier im Forum schon oft vorgestellt.
Also ich habe eine Tabelle (t1_cod4_v3_players_sd) in dieser gibt es die Spalten players_id und players_key. Jede id und jeder key sind einmalig.
In der zweiten Tabelle (t1_cod4_v3_nicks) sind zu den keys nicks gespeichert und die Anzahl wie oft welcher nick von welchem key benutz wurde (count).
Mein Ziel ist es alle keys auszugeben, mit dem Nick, der am häufigsten benutzt wurde und das ganze dann Alphabetisch nach den Nicks geordnet.
Das formuliere ich mal so:
Gib mir
die id (aus der Tabelle sd) und den
zugehörigen Nick (aus der Tabelle nicks)
aus der Tabelle
t1_cod4_v3_players_sd, kürzer mit sd bezeichnet
die mit der Tabelle
t1_cod4_v3_nicks, kürzer mit nicks bezeichnet
über die Bedingung, dass
der Wert in der Spalte players_key der Tabelle sd gleich dem Wert
in der Spalte nicks_key der Tabelle nicks ist
verknüpft ist
wobei
für jeden Wert von key nur der nick interessiert,
der den höchsten count-Wert besitzt.
und übersetze es nach SQL:
SELECT -- Gib mir
sd.players_id, -- die id
nicks.nicks_nicks -- und den nick
FROM -- aus Tabelle
t1_cod4_v3_players_sd sd -- t1_cod4_v3_players_sd, die über
-- den Alias sd angesprochen wird.
INNER JOIN -- und mit der Tabelle
t1_cod4_v3_nicks nicks -- t1_cod4_v3_nicks, die über den
-- Alias nicks angesprochen wird.
ON -- über die Bedingung gleicher Werte
sd.players_key = nicks.nicks_key -- in den Spalten players_key
-- bzw. nicks_key verknüpft ist.
-- es folgt eine [link:http://dev.mysql.com/doc/refman/5.0/en/correlated-subqueries.html@title=korrelierte Unterabfrage], um nur die Datensätze
-- auszuwählen, die je key den höchsten Wert in count aufweisen.
WHERE -- wobei
nicks.nicks_count = ( -- der Wert in count gleich dem
SELECT --
MAX(nicks2.nicks_count) -- Maximum der count-Werte ist
FROM -- aus der Tabelle
t1_cod4_v3_nicks nicks2 -- t1_cod4_v3_nicks - die wir
-- zur Unterscheidung über einen
-- anderen Aliasnamen ansprechen
-- müssen -
WHERE -- wobei die key-Werte in der
nicks2.nicks_key = nicks.nicks_key -- äußeren und inneren Tabelle
) -- übereinstimmen müssen, damit
-- wir den höchsten count-Wert
-- je nick bekommen.
Unterabfragen gehen in MySQL ab Version 4.1.
Zu Joins gibt es zwei Artikel in SELFHTML aktuell:
- Einführung in Joins
- Fortgeschrittene Jointechniken
Deine Tabellennamen halte ich für höchst verbesserungswürdig und ich halte von der Namenskonvention, einer Spalte noch ein Tabellennamen-Präfix beizufügen, überhaupt nichts. Es macht den SQL-Code nur schwerer lesbar.
Freundliche Grüße
Vinzenz