Problem mit WHERE Abfrage und %

Xandramat

Grünschnabel
Ich bin leider nicht sehr bewandert, was PHP und MySQL etc angeht. Ich kann lediglich genau die Sachen, die ich für mein Rollenspiel auch benötige.
Nun habe ich eine Art Galerie gebastelt, in der man ein Auswahlformular hat, in dem man entweder verschiedene Farben, Arten und Rassen auswählen kann, diese nehmen dann natürlich die jeweiligen Werte an. Oder aber es kann 'alle' ausgewählt werden, dies nimmt dann % an.

z.B. wie hier.
Code:
<select name="farbe" class="zeileblue" id="farbe">
        <option value="">Alle</option>
        <option value="Schimmel">Schimmel </option>
        <option value="Rappe">Rappe</option>
        <option value="Brauner">Brauner</option>
        <option value="Fuchs">Fuchs</option>
        <option value="Palomino">Palomino</option>
        <option value="Buckskin">Buckskin</option>
        <option value="Falbe">Falbe</option>
        <option value="Schecke">Schecke</option>
        <option value="Sonstige">Sonstige</option>
      </select>

Und nun sollte es aus der Datenbank natürlich die passenden Einträge auswählen.

PHP:
$start = $seite * $eintraege_pro_seite - $eintraege_pro_seite;

$farbe = $_POST["farbe"];
$art = $_POST["art"];
$rasse = $_POST["rasse"];






$abfrage = "SELECT * FROM bilder WHERE status = 'frei'AND farbe LIKE '$farbe' LIMIT $start, $eintraege_pro_seite";
$ergebnis = mysql_db_query($db, $abfrage, $verbindung);
while($row = mysql_fetch_object($ergebnis))

Beziehungsweise hier für die Seitenanzahl:

PHP:
$sql = "SELECT id FROM bilder  where status = 'frei' AND farbe LIKE '$farbe'";
$result = mysql_db_query($db, $sql, $verbindung);
$menge = mysql_num_rows($result);

$wieviel_seiten = $menge / $eintraege_pro_seite;

Und nun zum eigentlichen Problem.
Wenn ich Alle anwähle müssten rein logisch 36 Seiten zur Wahl gestellt werden. Es erscheinen jedoch lediglich 16. Das zeigt ja irgendwo, dass entweder nicht alle angezeigt werden oder aber irgend etwas anderes nicht stimmt.

Kann mir hier jemand helfen, dass meine Galerie endlich ganz funktioniert?
 
Nimm doch einfach eine einfache If-Abfrage:

PHP:
if(empty($farbe))
{
  $abfrage = "SELECT * FROM bilder WHERE status = 'frei' AND farbe LIKE '%$farbe%' LIMIT $start, $eintraege_pro_seite";
}
else{
  $abfrage = "SELECT * FROM bilder WHERE status = 'frei' LIMIT $start, $eintraege_pro_seite";
}
 
Zum einen, die if Option würd ich eher abraten,
da alle Operationen in der Datenbank Abfrage schneller verarbeitet werden als via if etc.

Jetzt zum Problem:

1. was mir aufgefallen ist, du solltest 1. zwischen 'frei' und AND ein Leerzeichen einstellen.

PHP:
$abfrage = "SELECT * FROM bilder WHERE status = 'frei'AND farbe LIKE '$farbe' LIMIT $start, $eintraege_pro_seite";

Hast du dir die Werte von
PHP:
$wieviel_seiten = $menge / $eintraege_pro_seite;
angesehen?
Vor allem wäre $menge und $eintraege_pro_seite wichtig.
Denn hier könnte man zum einen nachvollziehen was er macht.
(Die Größe der Datenbank abfrage).
Zum anderen würde ich dir empfehlen Alle Anfragen an die Datenbank korrekt zu Formulieren.

Zum Beispiel würde ich die Abfrage:
PHP:
$sql = "SELECT id FROM bilder  where status = 'frei' AND farbe LIKE '$farbe'";
so formulieren:
PHP:
$sql = 'SELECT `id` FROM `bilder`  where `status` = \'frei\' AND `farbe` LIKE \'' . $farbe . \'';
(Sind alles Single Quotes ')
Vorteil ist, das PHP diese Query schneller parsed.
Ist allgemein für Strings jeglicher Art zu empfehlen, da hier der String nicht geparsed wird.
Heißt allerdings auch, das du ein paar Single Quotes mehr hast, die man durch \' Maskieren muß.
Ist aber denk ich kein Problem.
Vor allem die Performance steigt auf längere Quelltexte zwar nicht merklich, aber bei schleifen hab ich schon mehrfach längere Parse Zeiten festgestellt wenn tausend Leute gleichzeitig auf ein Script zugreifen.
Aber es ist wie alles Geschmackssache.
Mir ist auch aufgefallen, das du die Datenbank via der Php Funktionen aufrufst.
Schau dir mal AdoDB an.
Kommt von sich aus mit mehreren verschiedenen Datenbank aus und kann via Php Binary Modul sogar noch beschleunigt werden.
Ist zwar nicht allzu einfach zu lernen aber via der Tutorials auf deren Homepage nicht unmöglich.
Verwende es seit 4 Monaten und bin hell auf begeistert.

;)

Chris
 
Bevor ichs vergess,
schau mal in phpMyAdmin nach, was deine letzte Query an Datenfeldern ausgibt.
Aus der Menge kannst du das Überprüfen was das Script ausgibt.
 
Zum einen, die if Option würd ich eher abraten,
da alle Operationen in der Datenbank Abfrage schneller verarbeitet werden als via if etc.
Wer hat dir das denn aufgebunden? Vor allem eine MySQL-LIKE Condition ist nicht gerade schnell. Des Weiteren ist ein Check, ob die Variable $farbe nicht existiert oder leer ist doch sehr, sehr schnell. Sofern man Konditionen für die Datenbankabfrage weglassen kann, und diese der Query-Performance nicht schaden, sollte man das auch tun.

Zum Beispiel würde ich die Abfrage:
PHP:
$sql = "SELECT id FROM bilder  where status = 'frei' AND farbe LIKE '$farbe'";
so formulieren:
PHP:
$sql = 'SELECT `id` FROM `bilder`  where `status` = \'frei\' AND `farbe` LIKE \'' . $farbe . \'';
(Sind alles Single Quotes ')
Vorteil ist, das PHP diese Query schneller parsed.
Ist allgemein für Strings jeglicher Art zu empfehlen, da hier der String nicht geparsed wird.
Auch das ist nicht immer richtig, und nur weil es auf einigen Seiten so steht, solltest du nicht ungeprüft Weisheiten in den Raum werfen. Abhängig von der PHP-Version kann das Konkatenieren an einen single-quoted String schneller ablaufen (in den meisten Fällen ist es also sinnvoll), jedoch muss auch ein einfach gequoteter String vom PHP Interpreter geparst werden - mit der Ausnahme, dass auf weniger Escape-Sequenzen geachtet werden muss, und die Variablenersetzung nicht stattfindet. Bevor aber extrem Unlesbarer Code in den Querystrings entsteht, sollte man sich zwei Mal überlegen, ob es für einen selbst wichtig ist aus einer "langsamen" PHP-Engine ein Minimum mehr rauszuholen. Das sind Optimierungsansätze, die man kennen sollte, aber nicht immer ist die Anwendung berechtigt - In den meisten Fällen ist der Gewinn sowieso unverhältnismäßig klein, da es nicht ins Gewicht fällt.

Nachdem man sich in die Grundlagen der Sprache eingearbeitet hat, sollte man sich meiner Meinung nach vor allem in Bezug auf vollständige Anwendungen und Modulen mit Frameworks beschäftigen, die die Arbeit wesentlich vereinfachen und angenehmer gestalten. Des Weiteren ist es bei jeder Aktivität mit Datenbanken sinnvoll keine handgemachten Escape-Mechanismen zu implementieren sondern über Prepared Statements und dergleichen zu gehen.
PHP:
// einfachstes Beispiel mit PDO
$db = new PDO('mysql:...');
$stmt = $db->prepare("SELECT foo FROM bar WHERE bla = ?;");
$stmt->execute(array($bla));
$foos = $stmt->fetchAll();
Mit dem Zend Framework beispielsweise kann man solche Abfragen noch um einiges netter gestalten.

Sobald man jedoch ein Framework drunterbaut, sind Performanceunterschiede mit Single- und Double-Quoted Strings eh die geringe Sorge... :rolleyes:
 
Auch das ist nicht immer richtig, und nur weil es auf einigen Seiten so steht, solltest du nicht ungeprüft Weisheiten in den Raum werfen. Abhängig von der PHP-Version kann das Konkatenieren an einen single-quoted String schneller ablaufen (in den meisten Fällen ist es also sinnvoll), jedoch muss auch ein einfach gequoteter String vom PHP Interpreter ge.....................................................
Mag sein das der Gewinn nur minimal ist,
aber jede Optimierung sollte doch benutzt werden oder?
Wer Zend als Framework benutzt ist in meinen Augen selbst schuld.
Ist in meinen Augen nicht wirklich sinnvoll ein so überzogenes Monster für Otto Normal Projekte zu verwenden.

Wer hat dir das denn aufgebunden? Vor allem eine MySQL-LIKE Condition ist nicht gerade schnell. Des Weiteren ist ein Check, ob die Variable $farbe nicht existiert oder leer ist doch sehr, sehr schnell. Sofern man Konditionen für die Datenbankabfrage weglassen kann, und diese der Query-Performance nicht schaden, sollte man das auch tun.
Nutzt dein Server nen Query Cache?
Wenn ja, dann kann man das getrost direkt in der Abfrage abarbeiten lassen.
Auch kann man für wiederkehrende Abfragen views einsetzen.
Das Beschleunigt das Auslesen nochmals.
Also ist hier der Datenbank Server Meilen schneller als Php.
Sorry, so seh ich das.
Außerdem, woher weißt du ob
PHP:
if(empty($farbe))
Unbedingt immer True ergibt.
Was ist wenn 0, false oder '' drin steht.
Was ist dann?
Mag sein, manchmal der weg über die Datenbank hinderlich und langsam ist, aber wenn der Cache erstmal gefüllt ist, läufts schnell.
Außerdem ist jede Schleife / Kondition eine bremse für den Interpreter von PHP.
Wenn du jetzt ne Sprache wie C++ hättest, würd ich dir sofort zustimmen.
Aber nicht bei PHP.
Wenn man keinen Op Code Cache hat, zieh ich persönlich die Datenbank für Abfragen vor.
Ansonsten hält sich das relativ die wagschale.
Mal ist der Php schneller mal MySQL.
Ist also geschmackssache.

Außerdem:
Abhängig von der PHP-Version
Wieviele Versionen sind denn noch am Markt?
PHP3: wird nicht mehr weiter entwickelt -- Fakto: tod
PHP4: Entwicklungsstop: also auch Fakto: tod
PHP 5: Version 5.3 ist am Kommen, ansonsten ist 5.2 aktuell.
PHP 6: kommt irgendwann vor Perl6 (hoffentlich)
Ganz ehrlich, wer heut noch auf PHP4 oder PHP5 vor 5.2 setzt ist einfach selbst schuld.
Die Distributionen bieten schon lange PHP 5 an.
(Auch in halbwegs aktueller Version)
Ich hab noch einen Server wo ich scripte via Benchmark direkt vergleichen kann.
Wo ich Single Quotes und Double Quotes direkt miteinander in diversen Tests vergleichen kann.
Und für mich öffnet sich der Blick, das Single Quotes erheblich schneller sind.
Außerdem wird bei double Quotes der Gesamte String geparsed.
Bei Single Quotes wird der Text als String interpretiert und muß nicht verarbeitet werden.
Daraus ergibt sich ein gewisser Performance Gewinn.
Allerdings muß ich zugeben, das bei einfach kleinen Applikationen der Gewinn sicherlich im mili Sekundenbereich liegt.
Aber sollte man nicht immer die Optimalere Variante verwenden?


Aber wir sollten uns auf sein Problem konzentrieren.

Wenn du die Ausgabe der Variablen postest, könnte man vielleicht Licht in dein dunkles Problem bringen.
Ohne das können wir dir nur schwer helfen.

chris

P.S.: Ich will jetzt net bösartig klingen, aber das sind meine Erfahrungen. Und ich kenn PHP seit Version 3.
Bin also kein .
Hab selbst schon mehrere Projekte gefahren und hunderte an eigene Bedürfnisse angepasst.
Soll auch keine Kriegserklärung sein.
War eigentlich nur gedacht, einem Anfänger in eine gewisse Richtung zu stoßen.
Ist immer abhängig von der Anwendung, der Hardware und mehr.
^^
 
Hi,

Soll auch keine Kriegserklärung sein.
War eigentlich nur gedacht, einem Anfänger in eine gewisse Richtung zu stoßen.

ich glaube nicht, dass das hier irgendjemand falsch auffasst. Es ist ja auch nett, dass Du Deine Erfahrungen teilen möchtest. Ich fürchte nur, dass Anfänger keine 10% davon verstehen. ;)
Bevor die in die Kleinstoptimierung einsteigen, müssen sie ja erstmal vernünftig programmieren lernen. Wenn's ein Performanceproblem gibt, liegt es meistens an wild verschachtelten Schleifen, in denen z.B. Abfragen an die DB gesendet werden, weil es einfach noch an SQL-Kennnissen mangelt.

LG
 
--- Nicht direkt problembezogene Äußerungen ab hier ---

Mag sein das der Gewinn nur minimal ist,
aber jede Optimierung sollte doch benutzt werden oder?
Bedingt. Sobald es die Verständlichkeit (stark) beeinträchtigt, und das Programm nicht nur von einer Person gepflegt werden muss, bin ich strikt gegen übermäßige Optimierung. Die Laufzeiteffizienz ist ein anderer Schuh als die Entwicklungseffizienz - Und letztere sollte immer vorgehen sofern es nötig ist.

Und wir unterhalten uns hier letztenendes über PHP, also bitte... ;)

Wer Zend als Framework benutzt ist in meinen Augen selbst schuld.
Ist in meinen Augen nicht wirklich sinnvoll ein so überzogenes Monster für Otto Normal Projekte zu verwenden.
Gerade dafür bietet es sich meiner Meinung nach besonders gut an. Es ist relativ leicht zu erlernen, transparent und vor allem entwicklungseffizient. Vor allem bei nicht allzu performancelastigen Einsatzgebieten macht es durchaus sinn die eh verfügbaren Ressourcen zu verwenden.
Anders sieht das bei größeren Projekten mit PHP in der Hauptrolle aus: Da werden Data Caching, Opt-Code Caching, Datenbankoptimierung, etc gebraucht, und jedes Zeichen im Code muss im besten Fall richtig sitzen. Für sowas bringt ein unverändertes Framework viel zu viel Ballast mit. Allerdings können Open Source Frameworks mit entsprechenden Anpassungen durchaus sinnvoll sein, da sie erprobt wurden, und nach einem gewissen Quasi-Best-Practice erbaut wurden.
Das alles muss man immer in Relationen sehen: Die Rechentechnik heutzutage bringt die Leistung mit, warum sonst laufen so viele Enterprise Webapplikationen über eine Java VM, und dann häufig auf einem Framework wie Spring, mit Templates auf Basis der JSTL, etc?

Nutzt dein Server nen Query Cache?
Wenn ja, dann kann man das getrost direkt in der Abfrage abarbeiten lassen.
Mir fällt spontan kein deutsches Hostingangebot unterhalb eines VPS ein, welches einen (ordentlichen) Query Cache mitbringt, zumal Caching immer dann kontraproduktiv ist, wenn der Speicher knapp ist. Da bringt der schnellste Speicher nichts, wenn ständig geswappt werden muss. Sicherlich hast du Recht, dass man an vielen Ecken optimieren kann (und vor allem in Sachen Query-Cache macht es natürlich Sinn die selben Abfragen zu verwenden).
Auch kann man für wiederkehrende Abfragen views einsetzen.
Richtig, dafür sind sie ja gedacht. Meiner Meinung nach leidet auf Grund von Views leider aber auch die Verständlichkeit. Und am Ende übersieht man, dass man mit einem View joint, welcher bereits einige Joins umfasst...

Also ist hier der Datenbank Server Meilen schneller als Php. Sorry, so seh ich das.
Datenbanken sind in dem schnell, wofür sie konzipiert wurden: mengen(relationale) Operationen. Vieles lässt sich heute auch komplett in Datenbanken evaluieren, wie laufzeiteffizient das jedoch ist, muss immer erst erprobt werden.
Vor allem problematisch wird es in Sachen Datenbanken immer dann, wenn diese auf einem anderen Host betrieben werden. Da mag das Sammeln der entsprechenden Daten noch so flott ablaufen, aber schließlich müssen auch die Daten hin- und hergeschickt werden, und dann überlegt man lieber zwei Mal was man hinschickt, und was man (in welchen Mengen) zurückbekommen möchte)

Außerdem, woher weißt du ob
PHP:
if(empty($farbe))
Unbedingt immer True ergibt.
Was ist wenn 0, false oder '' drin steht.
Was ist dann?
Ich weiß gar nicht dass das true zurückgibt (Habe ich das überhaupt vorgeschlagen?).

Mag sein, manchmal der weg über die Datenbank hinderlich und langsam ist, aber wenn der Cache erstmal gefüllt ist, läufts schnell.
Vorausgesetzt man hat genügend Cache... Und man muss letztenendes auch bedenken, dass eine suboptimale Konfiguration des Cachings größere Performanceprobleme mit sich bringen kann als kein Caching.
Die wenigsten, die PHP verwenden, haben Zugang (sowohl verständnisbedingt als auch technisch) zu derartigen Themen, und es ist in diesem Kontext auch nicht zweckmäßig.

Außerdem ist jede Schleife / Kondition eine bremse für den Interpreter von PHP.
Wenn du jetzt ne Sprache wie C++ hättest, würd ich dir sofort zustimmen.
Aber nicht bei PHP.
In (imperativen) Rechensystemen sind Schleifen immer Bremsen, das beschränkt sich nicht auf interpretierte Sprachen. Allerdings sind sie nun mal nötig um eine Sprache turing-vollständig zu machen (und dadurch überhaupt erst Rechenoperationen, wie wir sie implementieren, zu ermöglichen).

Wenn man keinen Op Code Cache hat, zieh ich persönlich die Datenbank für Abfragen vor.
Irgendwoher müssen die Daten schließlich kommen. Ob ich aber die Datenbank, und in welchem Umfang ich sie verwende, mache ich nicht davon abhängig, ob ich vom Interpreter interpretierten PHP-Code cachen kann, sondern in wiefern es nötig ist. Die beste Performance erzielt man durch effektives Bereithalten der Daten in schnellem Speicher - Sowohl Opt-Code als auch Daten sollten sinnvoll gecacht werden. Denn irgendwie müssen letztere auch erstmal entstehen. Und es ist (zumindest meiner Vermutung nach) wesentlich schneller die Daten bereits in einem leicht zu interpretierenden Format (zB serialisiert) bereithalten zu können als erst eine Anfrage an die DB zu fahren, deren Antwort dann (meist in einer Schleife) evaluiert und in entsprechende Datenkonstrukte erfasst werden muss.

Und da drückt der Schuh: Es ist eine Sache Benchmarks auf der Datenbank fahren zu lassen, und es ist eine andere Sache PHP zu benchmarken. Und es ist nochmal eine andere Sache beides im Verbund spielen zu lassen.

Ansonsten hält sich das relativ die wagschale.
Mal ist der Php schneller mal MySQL.
Ist also geschmackssache.
Es ist vor allem eine Sache des Einsatzzwecks. Relationale Datenbanken arbeiten gut mit Mengen, PHP arbeitet gut mit imperativen Befehlen.

Wieviele Versionen sind denn noch am Markt?
Die Versionierung von PHP beschränkt sich nicht nur auf eine Ganzzahl, sondern wird in Unterversionen und Releasegruppen (mit und ohne Entwicklungsstand) unterteilt. Ohne es auf Richtigkeit zu überprüfen, behaupte ich einfach mal, dass beispielsweise 5.2.3 und 5.2.9 diverse interne Aufgaben völlig unterschiedlich regeln.

Ich hab noch einen Server wo ich scripte via Benchmark direkt vergleichen kann.
Wo ich Single Quotes und Double Quotes direkt miteinander in diversen Tests vergleichen kann.
Und für mich öffnet sich der Blick, das Single Quotes erheblich schneller sind.
Außerdem wird bei double Quotes der Gesamte String geparsed.
Bei Single Quotes wird der Text als String interpretiert und muß nicht verarbeitet werden.
Um das zu überprüfen, müsste ich erst in die PHP-Sources schauen. Für mich macht es von der theoretischen Betrachtung her aber keinen Unterschied, ob der Interpreter einen sq-String oder dq-String betrachtet, da er sowohl beim einen als auch beim anderen Character-weise drüberwuselt. Lediglich ist die Auswertung bei double quotes umfangreicher, dafür aber auch die Funktionalität.

Aber sollte man nicht immer die Optimalere Variante verwenden?
Was ist optimal? ;) Ist ein Maximum an Laufzeiteffizienz optimal? Ist eine minimale Arbeit und Mühe, die in die Entwicklung des Programms geflossen sind optimal? Ist es irgendwas zwischendrin? Jede Optimierung muss erst gefunden, entwickelt und erprobt werden. Zudem wird eine Dokumentation erforderlich. Man braucht also somalsorum wesentlich mehr Zeit und Mühe um die Laufzeit zu optimieren, was es betrachtungsabhängig macht, ob man das als optimal bewertet.

P.S.: Ich will jetzt net bösartig klingen, aber das sind meine Erfahrungen. Und ich kenn PHP seit Version 3.
Ditto. Und man schaut auch gerne über den Tellerrand, lernt dazu, und lässt sich eines Besseren belehren. Relevant ist meiner Meinung aber auch, in welche Relationen man das ganze setzt. Interpretierte Sprachen sind nun mal langsamer als compilierte. Auch sind bestimmte Sprachkonstrukte nicht sonderlich schnell. Aber sie machen das tägliche Leben womöglich bequemer und verständlicher, und sollten deshalb nicht in jedem Fall diskreditiert werden.

Soll auch keine Kriegserklärung sein.
So habe ich es auch nicht aufgefasst. :)

War eigentlich nur gedacht, einem Anfänger in eine gewisse Richtung zu stoßen.
Das ist nett, und hoffentlich fruchtet es auch rechtzeitig. ;)
 
Zurück