Query Optimierung: Queries zusammenführen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Query Optimierung: Queries zusammenführen

    hallo, ich mal wieder,
    man möge eskaum glauben, aber mein erstes projekt steht fast, hab nur ein problem (ich vermute es sind wiedermal grundlagen und für euch ein klacks ;) )

    ich hab nun meine unterseite, auf der alle banner angezeigt werden, wenn man auf einen banner klickt öffnet sich in einem popup ein frameset in dem oben im kopf ein countdown zu sehen ist und unten die betreffende seite, wenn der countdown abgelaufen ist, kann man einen button klicken und man bekommt punkte gutgeschrieben. die aufladungen des banners wird entsprechend um 1 verringert und in einer dritten tabelle wird der user, die bannerid und der klickzeitpunkt geloggt. jetzt zu meinem problem:

    auf der hauptseite werden alle banner angezeigt, ich will aber zum einen die weg haben deren aufladungen 0 betragen, die von einem user selbst eingetragen wurden oder die noch im reload sind.

    die ersten beiden bekomme ich hin weil das nicht tabellenübergreifend ist, einfach beim ersten WHERE aufladungen > 0 und beim 2. WHERE userid != $_SESSION['userid'] (ich denke mal so geht das??!?!?)

    beim dritten ist aber jetzt das große problem, in der tabelle 'paidbanner' hab ich als wert die reloadzeit in sekunden und in der tabelle 'paidbanner_klicks' hab ich den zeitpunkt des klciks auf den banner x
    wenn [aktuelle zeit] - [klickzeitpunkt] < [reloadzeit] ist soll der banner nicht angezeigt werden, ansonstn aber schon, wie mach ih denn sowas tabellenübergreifend. ich will ja die datenbankperformance so gut wie möglich halten und deswegen nicht so viele abfragen reinhauen.

    ich danke wie immer im vorraus für antworten,
    euer mossi
  • also ich versuche mein probel nochmal etwas genauer auszuführen, weil der link und auch joins, so lieb das gemeint is, glaube ich nicht wirklich weiterhelfen, aber ich versuchs mal genauer auszuführen:

    ich hab folgende tabellen (relevante daten für meinen lösungsansatz mach ich mal fett und unterstrichen)
    member -> userid, aktiviert, nickname, passwort, email, punkte, anmeldung, lastlogin, anzahl_logins
    paidbanner -> bannerid, userid, website, banneradresse, vergütung, aufenthaltsdauer, reloadsperre, aufladungen
    paidbanner_klicks -> klickid, userid, bannerid, klickzeitpunkt

    da dieses script ein eigenes modul wird ist es in einem eigenen ordner und die ausgangsdatei ist die index.php, in der sollen alle banner angezeigt werden, die 1. mehr als 0 aufladungen haben, 2. nicht von einem selbst eingestelltwurden und 3. die nicht in der reloadsperre sind
    1. geht ganz einfach in der sql abfrage selbst nämlich mit WHERE aufladungen >0
    auch 2. hab ich mit WHERE userid <> $_SESSION['userid'] lösen können
    bei drittens hab ich das große problem, ob ein banner in der reloadsperre ist oder nicht lässts sich ja ganz einfach rausfinden (nicht in der reloadsperre: reloadsperre < aktuelle zeit - klickzeitpunkt) das ist nicht das problem, es ist nur dass ich die banner mit einer while schleife ausgebe und wenn ich jedes mal wenn ein neuer banner geladen wird erst auf die paidbanner_klicks tabelle zugegriffen werden muss um das alles zu errechnen dann ist klar dass das bei 100 usern gleichzeitig, die sich 100 banner anzeigen lassen wollen ein problem entstehen können.

    ich hoffe ich konnte mein problem näherbringen, ich poste nochmal den code wie er jetzt aussieht, ich ihn aber nicht haben will wenn es geht:

    Quellcode

    1. <?
    2. if ($_SESSION['eingeloggt'] == TRUE){
    3. include("dbconnect.php");
    4. $abfrage = "SELECT * FROM paidbanner, WHERE aufladungen > '0' AND userid <> $_SESSION[userid] ORDER BY vergütung DESC";
    5. $ergebnis = mysql_query($abfrage);
    6. while($row = mysql_fetch_object($ergebnis)){
    7. $banner['bannerid'] = $row->bannerid;
    8. $banner['website'] = $row->website;
    9. $banner['banneradresse'] = $row->banneradresse;
    10. $banner['reloadsperre'] = $row->reloadsperre;
    11. $abfrage2 = "SELECT * FROM paidbanner, paidbanner_klicks WHERE userid = $_SESSION[userid] AND bannerid = $banner[bannerid]";
    12. $ergebnis2 = mysql_query($abfrage2);
    13. $row2 = mysql_fetch_object($ergebnis2);
    14. $klick['klickzeitpunkt'] = $row2->klickzeitpunkt;
    15. if ($banner['reloadsperre'] < time() - $klick['klickzeitpunkt']){
    16. echo "<a href=\"module/paidbanner/paidbanner.php?userid=$_SESSION[userid]&bannerid=$banner[bannerid]\" target=\"_blank\"><img src=\"$banner[banneradresse]\" width=\"468\"
    17. height=\"60\" border=\"0\" alt=\"Banner $banner[bannerid]\" /></a><br />";
    18. }
    19. }
    20. } else { echo "Sie sind nicht eingeloggt oder Ihre Session ist abgelaufen. Loggen Sie sich ein und versuchen Sie es erneut."; }
    21. ?>
    Alles anzeigen
  • geh doch mal schrittweise vor.

    Step 1:
    fehler fixen

    Quellcode

    1. SELECT * FROM paidbanner, paidbanner_klicks WHERE userid = $_SESSION[userid] AND bannerid = $banner[bannerid]

    wo stellst du den bezug zwischen den tabellen her? du musst richtig joinen.

    Quellcode

    1. SELECT *
    2. FROM paidbanner p
    3. INNER JOIN paidbanner_klicks pk
    4. ON p.bannerid = pk.bannerid
    5. WHERE userid = $_SESSION[userid]
    6. AND pk.bannerid = $banner[bannerid]


    Step 2: Ersetze den php code durch sql code (+variablen escapen, falls userinput)

    vorher:

    Quellcode

    1. SELECT * FROM paidbanner p INNER JOIN paidbanner_klicks pk ON p.bannerid = pk.bannerid WHERE userid = $_SESSION[userid] AND pk.bannerid = $banner[bannerid]
    2. if($reloadsperre < time()-$sql['klickzeitpunkt']) {
    3. ....
    4. }


    nachher:

    Quellcode

    1. SELECT *
    2. FROM paidbanner p
    3. INNER JOIN paidbanner_klicks pk
    4. ON p.bannerid = pk.bannerid
    5. WHERE userid = $_SESSION[userid]
    6. AND pk.bannerid = $banner[bannerid]
    7. AND ".$reloadsperre." < NOW() - klickzeitpunkt;



    Step 3: Führe die Abfragen zusammen

    vorher:

    Quellcode

    1. SELECT * FROM paidbanner WHERE aufladungen > '0' AND userid <> $_SESSION[userid] ORDER BY vergütung DESC
    2. SELECT *
    3. FROM paidbanner p
    4. INNER JOIN paidbanner_klicks pk
    5. ON p.bannerid = pk.bannerid
    6. WHERE userid = $_SESSION[userid]
    7. AND pk.bannerid = $banner[bannerid]
    8. AND ".$reloadsperre." < NOW() - klickzeitpunkt;


    nachher:
    bitte probiers mal selbst ;)
  • edit: hatte zwar schonml was andres gepostet was nicht funktioniert hatte, aber hab jetz ne ganz neue idee bekommen. ich will ja das alle banner geladen werden, also auch die die garnich in der andern tabelle auftauchen, hab bei selfhtml jetz gelesen dass ich da nen LEFT JOIN oder RIGHT JOIN nehmen muss, hab mich da mal reingelesen und als ergebnis das rausbekommen:

    Quellcode

    1. SELECT
    2. paidbanner.bannerid,
    3. paidbanner.userid,
    4. website,
    5. banneradresse,
    6. vergütung,
    7. aufenthaltsdauer,
    8. reloadsperre,
    9. aufladungen,
    10. klickid,
    11. paidbanner_klicks.userid,
    12. paidbanner_klicks.bannerid,
    13. klickzeitpunkt,
    14. FROM
    15. paidbanner
    16. LEFT JOIN
    17. paidbanner_klicks
    18. ON paidbanner.bannerid = paidbanner_klicks.bannerid
    19. AND $_SESSION[userid] = paidbanner_klicks.userid
    20. WHERE
    21. aufladungen > 0
    22. AND paidbanner.userid <> $_SESSION[userid]
    23. AND reloadsperre < NOW() - klickzeitpunkt"
    Alles anzeigen


    problem is dass ich jetzt nen fehler ausgegeben bekomme, den ich vorher nich bekommen:
    Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource in /var/www/html/web49/html/pointies/module/paidbanner/index.php on line 33
    dabeu habe ich in zeile 33 nichts verändert, also dden betreffenden befehl nicht angerührt, wo ist mein fehler? ich poste mal die gesamte datei wie sie jetzt aussieht (bitte die unordnung zu entschuldigen, ich räum den code auf sobald es funzt ;) )

    Quellcode

    1. <?
    2. if ($_SESSION['eingeloggt'] == TRUE){
    3. include("dbconnect.php");
    4. $abfrage = "SELECT
    5. paidbanner.bannerid,
    6. paidbanner.userid,
    7. website,
    8. banneradresse,
    9. vergütung,
    10. aufenthaltsdauer,
    11. reloadsperre,
    12. aufladungen,
    13. klickid,
    14. paidbanner_klicks.userid,
    15. paidbanner_klicks.bannerid,
    16. klickzeitpunkt,
    17. FROM
    18. paidbanner
    19. LEFT JOIN
    20. paidbanner_klicks
    21. ON paidbanner.bannerid = paidbanner_klicks.bannerid
    22. AND $_SESSION[userid] = paidbanner_klicks.userid
    23. WHERE
    24. aufladungen > 0
    25. AND paidbanner.userid <> $_SESSION[userid]
    26. AND reloadsperre < NOW() - klickzeitpunkt";
    27. $ergebnis = mysql_query($abfrage);
    28. while($row = mysql_fetch_object($ergebnis)){
    29. $banner['bannerid'] = $row->bannerid;
    30. $banner['website'] = $row->website;
    31. $banner['banneradresse'] = $row->banneradresse;
    32. echo "<a href=\"module/paidbanner/paidbanner.php?userid=$_SESSION[userid]&bannerid=$banner[bannerid]\" target=\"_blank\"><img src=\"$banner[banneradresse]\" id=\"$banner[bannerid]\" width=\"468\" height=\"60\" border=\"0\" alt=\"Banner $banner[bannerid]\" onclick=\"$banner[bannerid].width:0px;$banner[bannerid].height:0px;\" /></a><br />";
    33. }
    34. } else { echo "Sie sind nicht eingeloggt oder Ihre Session ist abgelaufen. Loggen Sie sich ein und versuchen Sie es erneut."; }
    35. ?>
    Alles anzeigen


    danke für eure hilfe
    euer mossi

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Mossi ()

  • Der kleinste Fehler den man machen kann, danke d0nut, da sieht man wer neu im geschäft ist und wer erfahrung an den tag legt ;)

    hab jetzt folgendes problem, als ich aus den ganzen testzwecken noch daten in der paidbanner_klicks tabelle hatte wurden mir die banner auch prima angezeigt, jedoch wurden die banner auch dann noch angezeigt wenn sie eigentlih im reload sein müssten und deswegen ausbleiben sollten. ich hab ums zu testen einfach mal die paidbanner_klicks tabelle leer gemacht, kann ja sein dass sich ein neues mitglied registriert und noch nie einen klick gemacht hat... und was stelle ich fest, es werden keine banner angezeigt... hmmm

    ich habe mich also entschlossen folgende codezeile erstmal rauszunehmen und später evtl in php mit in die while-schleife zu packen

    Quellcode

    1. AND reloadsperre < NOW() - klickzeitpunkt


    soweit so gut, nun bekomme ich alle banner angezeigt, aber es breitet sich das nächste problem aus, worüber ich nirgends etwas lesen kann und auch alles was aus meiner denkweise hätte logisch sein können funktioniert nicht, und zwhabe ich ja folgende SELECT in der abfrage

    Quellcode

    1. SELECT
    2. paidbanner.bannerid,
    3. paidbanner.userid,
    4. website,
    5. banneradresse,
    6. vergütung,
    7. aufenthaltsdauer,
    8. reloadsperre,
    9. aufladungen,
    10. klickid,
    11. paidbanner_klicks.userid,
    12. paidbanner_klicks.bannerid,
    13. klickzeitpunkt
    Alles anzeigen


    deklariere in der while-schleife dann aber folgende variable in php

    Quellcode

    1. $banner['bannerid'] = $row->bannerid;

    und da ist das problem, ich frage ja nicht direkt bannerid ab sondern immer mit dem tabellenpräfix und dem punktoperator... hab jetzt alles mögliche versucht, hab versucht aus dem fetch object nen fetch assoc zu machen, mit präfix, ohne präfix den $row gemacht, aber jedes mal bekomme ich nur fehler, und wenn ich einen banner klicke, dann soll ja auf diese weise im Link die bannerid übergeben werden, und diese ist immer leer oder es gibt ne fehlermeldung (dieselbe wie im letzte post)

    bitte helft einem lernwilligen, auf das mein script bald fertig wird, ich bin so kurz davor :/

    euer mossi
  • In welcher Einheit hast du die Reloadsperre angegeben? Fall es Sinn macht die Sekunden zu vergleichen probiers mit

    Quellcode

    1. AND UNIX_TIMESTAMP(reloadsperre) < UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(klickzeitpunkt)


    Für dein nächstes Problem gibt es etwas namens Alias - das gibt es sowohl für Tabellen, als auch wie hier für Spalten.

    Quellcode

    1. SELECT
    2. paidbanner.bannerid AS bannerid,
    3. paidbanner_klicks.bannerid AS klicks_bannerid,
    4. ...


    Gruß
  • hallo donut und danke für die hilfe,
    habe es mit alias schon probiert, hatte aber ne fehlermeldung und die hab ich auch diesmal wieder, vielleicht könntest du mir den peinlicherweise wahrscheinlich von mir übersehenen fehler auf anhiebe sehen? bin wie schon so oft erwähnt noch totaler datenbank-neuling und hab mir scheinbar gleich das dickste projekt rausgesucht :/

    so sieht mein code aus

    Quellcode

    1. SELECT
    2. paidbanner.bannerid AS bannerid,
    3. paidbanner.userid,
    4. website,
    5. banneradresse,
    6. vergütung,
    7. aufenthaltsdauer,
    8. reloadsperre,
    9. aufladungen,
    10. klickid,
    11. paidbanner_klicks.userid,
    12. paidbanner_klicks.bannerid AS klicks_bannerid,
    13. klickzeitpunkt
    14. FROM
    15. paidbanner
    16. LEFT JOIN
    17. paidbanner_klicks
    18. ON bannerid = klicks_bannerid
    19. AND $_SESSION[userid] = paidbanner_klicks.userid
    20. WHERE
    21. aufladungen > 0
    22. AND paidbanner.userid <> $_SESSION[userid]
    23. AND UNIX_TIMESTAMP(reloadsperre) < UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(klickzeitpunkt)
    Alles anzeigen


    und fehler ist wieder der mir schon bekannte
    Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource...
    und dann hab ich noch eine weitere frage wegen der unix timestamp... nicht jeder user hat für jeden banner nen klickzeitpunkt, da wie egsagt ja auch user neu dazustoßen können oder neue banner eingetragen werden die noch niemand geklickt hat, denmach existiert zunächst keine datei die nen klickzeitpunkt definiert, funktioniert dein vorschlag aus dem lezzten post trotzdem?

    liebe grüße und danke für deine geduld mit mir
    mossi
  • nach langem hin und herprobieren, umstellen, austauschen, testen, testen und testen und dann anschließend ner kompletten neugestaltung des queries, hab ich es tatsächlich hinbekommen mein bannerscript fetigzustellen, es fehlt lediglich etwas javascript um das ganze etwas optisch aufzuwerten und einige feinheiten, inklusive dem modul dass man eigene banner einstellenkann aber das sollte ein leicgtes sein...
    wer sich das dingen mal ansehen will kann das gerne tun -> mossi.biz/pointies

    liebste grüße und danke an alles hilfen, besonders an donut in dickes danke fpr deine geduld, werde mich dann nochmal im javascriptbereich melden ^^
    euer mossi