Was ist besser

Napofis

require 'brain.php';
Hi @ all,

ich hab da 2 kleine Frage die mich jetzt schon öfters beschäftigt.

Bei manchen SQL Abfrage hab ich die Wahl zwei Tabellen zu verknüpfen oder ein Sub Select zu nutzen.
Welche der beiden Varianten ist nun die bessere?

Und Nummer 2, spielt die Reihenfolge der 'WHERE' Kriterien eine Rolle?
Also zB lassen sich Zahlen schneller vergleichen als Strings.

Also stimmt es das es schneller geht wenn man erst nach Zahlen Filtert und dann nach Strings, bei größeren Ergebnismengen :confused:


Ich hoffe Ihr versteht mich.


MFG Napofis
 
Bei manchen SQL Abfrage hab ich die Wahl zwei Tabellen zu verknüpfen oder ein Sub Select zu nutzen.
Welche der beiden Varianten ist nun die bessere?
Das muss man von Fall zu Fall entscheiden. Eine allgemein gültige Regel gibt es hier nicht.

Und Nummer 2, spielt die Reihenfolge der 'WHERE' Kriterien eine Rolle?
Also zB lassen sich Zahlen schneller vergleichen als Strings.

Also stimmt es das es schneller geht wenn man erst nach Zahlen Filtert und dann nach Strings, bei größeren Ergebnismengen :confused:
Kann sein, muss aber nicht. Die meisten Datenbanksysteme optimieren Abfragen bevor sie sie ausführen. Insofern hast du sowieso keinen Einfluss darauf, in welcher Reihenfolge die WHERE-Klausel abgearbeitet wird.

Grüße,
Matthias
 
Hi ich noch mal :)
ich meine DB Klasse jetzt ein wenig erweitert um Infos zu den Abfragen zu sammeln.

Hier mal ein Auszug der Ausgabe:

Code:
Protokoliere Abfragen: 13
....
    * Query: SELECT *, `xxx` FROM `yyy` WHERE `id` IN ( SELECT `zzz` FROM `www` WHERE `vvv`=85 ) ORDER BY RAND()
    * Error:
    * Betroffenen Zeilen:
    * Zeilen: 3
    * Dauer der Abfrage: 8.68 ms

    * Query: SELECT `name`,`link`, IF (`latitude`>48.3654574, IF (`longitude`>10.8947684, SQRT(POWER(`latitude`-48.3654574,2) + POWER(`longitude`-10.8947684,2)), SQRT(POWER(`latitude`-48.3654574,2) + POWER(10.8947684-`longitude`,2)) ), IF (`longitude`<=10.8947684, SQRT(POWER(48.3654574-`latitude`,2) + POWER(10.8947684-`longitude`,2)), SQRT(POWER(48.3654574-`latitude`,2) + POWER(`longitude`-10.8947684,2)) ) ) AS `dist` FROM `yyy` WHERE `version`>=2 AND `id`!=2 ORDER BY `dist` ASC LIMIT 5
    * Error:
    * Betroffenen Zeilen:
    * Zeilen: 5
    * Dauer der Abfrage: 0.04 ms

    * Query: SELECT COUNT(`id`) AS `st` FROM `yyy JOIN `xxx` ON `zzz`=`id` WHERE `vvv`="85"
    * Error:
    * Betroffenen Zeilen:
    * Zeilen: 1
    * Dauer der Abfrage: 8.2 ms

....


Es nimmt sich wirklich nicht viel, ob JOIN oder subSelect.
Nunja aber was ich bis jetzt herausgefunden habe ist, das es auf jeden Fall besser ist sortier und filter Funktionen den SQL Server zu überlassen.
Und vor allem die Transferierte Datenmenge so klein wie möglich zu halten.

Aber gib es noch mehr Dinge die ich beachten muss bzw verbessern kann um die Performance meiner Abfragen zu steigern?
Ich bin für jeden Tipp dankbar.


MFG Napofis
 
Das muss man von Fall zu Fall entscheiden. Eine allgemein gültige Regel gibt es hier nicht.

Genau, ich hatte mal eine Query, wo ich zuerst mit einem Subselect die Daten geholt habe (12 verschiedene Tabellen), diese Query hat bei ~9000 Datensätze rund 17,xxxxx Sekunden benötigt, als ich dann die Query auf normale Bedingungen/Verknüpfungen geändert habe, ist die Query-Zeit auf 0,003xxx Sekunden gefallen, obwohl ich vorher feste davon überzeugt war, das es mit Subquerys wohl am schnellsten gehen würde.
 
Es nimmt sich wirklich nicht viel, ob JOIN oder subSelect.
Wie hast du das rausgefunden? Die geposteten Querys sind nicht equivalent zueinander!
Aber gib es noch mehr Dinge die ich beachten muss bzw verbessern kann um die Performance meiner Abfragen zu steigern?

Indezes können weiterhelfen und das System stark beschleunigen. Jedoch sind sie mit bedacht zu verwenden. Falsch eingesetzt (z.B. falsche Sortierung des Index) bewirken sie nämlich das Gegenteil!
 
Hi,

ja die Abfragen sind nicht gleich aber es waren mehrere Verschiedene.
Das ganze diente mehr für Debug Zwecke, als einen Benchmark.


Das mit dem Index hab ich auch berücksichtigt, zb. werden die Tabellen von einem kleinen Wartungsprogramm in gewissen Abständen optimiert und von Grund auf nach dem Index Sortiert so wie Sie am meisten gebraucht werden.

Eine Tabelle die sich kaum verändert bekommt mehrere Indizes die für Abfragen wichtig sind.
Eine Tabelle die oft geändert wird bekommt nur die nötigsten.


MFG Napofis
 
Moin Napofis,

[OffTopic]
Hi,
ja die Abfragen sind nicht gleich aber es waren mehrere Verschiedene.
So einen Brüller hab ich seit der letzten Bundestagswahl nicht mehr gelesen.

Eine Tabelle die sich kaum verändert bekommt mehrere Indizes die für Abfragen wichtig sind.
Eine Tabelle die oft geändert wird bekommt nur die nötigsten.
Und wie du aus dir gegebenen Kommentaren diese Schlussfolgerung ableitest, da komm ich auch nicht mit.

Aber viel Glück und Frohe Ostern.
Biber
[/OffTopic]
 
@Biber
Sehr hilfreicher Beitrag!

@Napofis
Anhand deiner Vergleiche kannst du keinerlei Schlussfolgerungen ziehen. Zur Zeit vergleichst du Äpfel mit Birnen!

Das regelmäßige Neusortieren von Daten ist unnütz! Zum einen blähst du nur das Transaktions-Log auf (hat MySQL sowas überhaupt?) zum anderen machen genau sowas Indexe. Beim Index wird die Sortierung mit angeben.
Das bedeutet: suchst du über eine Spalte mit Index in der z.B. eine Menge steht den Tupil mit der größten Menge
SQL:
SELECT * from table where amount = (Select MAX(amount) from table)
Ohne Index: Alle Datensätze müssen durchsucht werden --> Laufzeit erhöht sich mit steigender Anzahl von Datensätzen
Mit Index absteigend sortiert: Die größte Menge steht ob --> Laufzeit nahezu gleichbleibend
Mit Index aufsteigend sortiert: Die größte Menge steht unten --> Laufzeit steigt mit steigender Anzahl von Datensätzen.

Das regelmäßige umsortieren ist, wie gesagt unnötig und teuer!

Die Indizes sollte auch nicht auf mit Blick auf die Änderungen in der Tabelle vergeben werden sondern mit Blick auf die Abfragen die du ausführst. PK ist so ein Fall (automatisch mit Index): Ein Suche über den PK einer Tabelle geht sehr schnell.
Ein allgemeingültige Aussage lässt sich hier aber nicht treffen. Das kannst du nur durch ausprobieren herausfinden, wo ein Index hilfreich ist und wo nicht, da nur du alle Abfragen kennst und auch weißt wie das ER Modell aussieht
 
Moin Nico Graichen,

@Biber
Sehr hilfreicher Beitrag!
Ja, sorry, war nicht sehr konstruktiv.
War auch mehr ein lautes Kopfschütteln darüber, dass nach einer Frage, die ich als durchaus vom ernsthaftem Interesse getrieben aufgefasst habe, und auf die ja durchaus die ebenso ernstgemeinte (und begründete!) Antwort kam "Lässt sich nicht pauschal sagen." so ein Feedback kam.

Wenn ich noch versuchen wollte, etwas Konstruktiveres nachzuschieben, dann in etwa:

Es lässt sich nicht pauschal sagen, weil
- es abhängig ist von der Kardinalität (anzahl unterschiedlicher Werte je Schlüssel/Fremschlüsselspalte) in jeder einzelnen Tabelle
- der Art der Beziehung zwischen den beiden Tabellen (1:1, 1:n, m:n)
- dem Größenverhältnis der beiden Tabellen
- der zu erwartenden Satzanzahl/dem Resultset der einzelnen Tabellen, also ob 20 von 40 oder eher 20 von 400000 Datensätzen der Bedingung entsprechen.
- dem Nutzen oder Nichtnutzen vorhandener Indizes durch den Optimizer

--< deshalb: Jede Abfrage und deren Variationen per EXPLAIN prüfen und per Trial & Error an ein (vorläufiges) Optimum herantasten

Und auf keinen Fall solche Aktionen wie "Indizes nur für Tabellen mit geringer oder hoher Änderungsfrequenz anlegen" an die Wand hängen.

Grüße
Biber
 
...
Zum einen blähst du nur das Transaktions-Log auf (hat MySQL sowas überhaupt?)
....

Ich bin nicht ganz sicher aber BDB, InnoDBs sind Tranksaktionssicher.
Der Rest wie MyISAM, ISAM , MEMORY, ... nicht.



Danke für die Hilfe, ich werd das alles mal in Ruhe ausprobieren.

Der Sinn des ganzen ist einfach nur das sich mein Seiten möglichst schnell aufbauen.
Das die Besucher nicht so lang warten müssen.


MFG und schöne Ostern
Napofis
 
Zurück