php.de

Zurück   php.de > Webentwicklung > Datenbanken

Datenbanken SQL und Co

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 22.03.2007, 20:52  
Erfahrener Benutzer
 
Registriert seit: 13.08.2007
Beiträge: 1.976
KingCrunch befindet sich auf einem aufstrebenden Ast
KingCrunch eine Nachricht über ICQ schicken KingCrunch eine Nachricht über AIM schicken KingCrunch eine Nachricht über MSN schicken KingCrunch eine Nachricht über Yahoo! schicken
Standard SELECT über zwei Tabellen

Mal wieder eine lustige Performance-Frage

Geht darum, dass ich eine Abfrage über zwei Tabellen machen muss, bei den eine schon durch eine äußere Bedingung eingeschränkt wird. Konkret entstanden so 3 Beispiele:

So würde ich das spontan aussm Bauch raus so machen
Code:
SELECT a.name FROM tabelle1 AS a, tabelle2 AS b WHERE (b.id = $id) AND (a.id = b.tabelle1_id)
Nun hat mir der DB-Adapter eines Frameworks das daraus gezaubert
Code:
SELECT a.name FROM tabelle1 AS a INNER JOIN tabelle2 AS b WHERE (b.id = $id) AND (b.tabelle1_id = a.id)
Eine dritte Möglichkeit, die dann aus einer Diskussion entstanden ist, ist die über einem Sub-SELECT
Code:
SELECT a.name FROM tabelle1 AS WHERE a.id IN (SELECT b.tabelle1_id FROM tabelle2 AS b WHERE b.id = $id)
Kann mir jetzt jemand mit etwas mehr SQL-Erfahrung erklären, wieso eins davon performanter ist, als das andere ^^ Es gab schon Diskussionen darüber, aber irgendwie endeten alle dadrin, dass alle 3 Varianten aufwendig werden können -.-

Bisher erscheint mir die 3te Variante am logischsten (gibs das Wort? ^^)
__________________
Nicht jeder Fehler ist ein Bug.
KingCrunch ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 22.03.2007, 21:51  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Hallo,
es heißt SELECT .. FROM table1, table2, .. Abfragen seien deprecated, da nicht performant. Die Temp-Table enthält demnach wohl table1-datensätze x table2-datensätze und läuft dann erst mit der Bedingung darüber.

JOINs sind dabei viel einschränkender, denn table1-datensätze, auf die WHERE zutrifft x tabl2-datensätze. Danach erst wird die Temp-Table auf die ON-Bedingung getestet.
Wie das nun bei deinem Beispiel ist, wenn in der WHERE-Bedingung bereits Bezug auf den JOIN genommen wird, weiß ich nicht.
Mir wurde beigebracht, die JOIN-Bedingung in den ON-Teil zu schreiben (der Performance-Gewinn ergäbe dann für mich auch Sinn).

Letzteres dürfte ebenfalls sehr schnell sein, ich könnte mir jedoch vorstellen, dass hier Performance verloren geht, da intern vielleicht zwei Prozesse gestartet werden müssen? Ist aber geraten! Ich weiß nicht wie das tatsächlich programmiert wurde.
Super-abwärts kompatibel sind Sub-SELECTs ja auch nicht.

Ich persönlich verwende das SELECT .. FROM .. INNER JOIN .. ON .. WHERE Konstrukt.

Zumindest Version 1 ist für die Tonne
Zergling-new ist offline   Mit Zitat antworten
Alt 22.03.2007, 22:36  
Erfahrener Benutzer
 
Registriert seit: 13.08.2007
Beiträge: 1.976
KingCrunch befindet sich auf einem aufstrebenden Ast
KingCrunch eine Nachricht über ICQ schicken KingCrunch eine Nachricht über AIM schicken KingCrunch eine Nachricht über MSN schicken KingCrunch eine Nachricht über Yahoo! schicken
Standard

Wundervoll, da hat mich ja das Framework gerettet
Zitat:
Zitat von Zergling
Wie das nun bei deinem Beispiel ist, wenn in der WHERE-Bedingung bereits Bezug auf den JOIN genommen wird, weiß ich nicht.
Mir wurde beigebracht, die JOIN-Bedingung in den ON-Teil zu schreiben (der Performance-Gewinn ergäbe dann für mich auch Sinn).
Die Frage habe ich mir noch garnicht gestellt. Bezieht sich nicht die WHERE-Bedingung sowieso auf den JOIN und nicht "vor" den JOIN? OK, grad etwas verwirrt: Was unterscheidet an der Stelle das ON vom WHERE? Meine pauschale Idee ist jetzt, dass sich das WHERE auf die gesamte Abfrage bezieht, während sich das ON nur auf die Verbindung zwischen der gesuchten und der verbundenen Tabelle bezieht. Und gaaaanz blöde Frage am Ende: Sind die Bedingungen von ON "quasi identisch" mit denen vom WHERE? Also könnte ich statt WHERE jetzt einfach ON schreiben?

Abwärtskompatibilität ist natürlich auch ein Faktor, den ich gerne berücksichtigen möchte. Wie weit die zurück gehen, wird sich sicher irgendwo finden lassen. Wenn sich der Performance-Gewinn (falls überhaupt) nicht rechnet, bliebe dann nur noch JOIN. Von der Performance könnte ich mir so gesehen denken, dass zwei "leichte" Prozesse auch leichter sein könnten, als ein aufwendiger.
__________________
Nicht jeder Fehler ist ein Bug.
KingCrunch ist offline   Mit Zitat antworten
Alt 23.03.2007, 00:20  
Erfahrener Benutzer
 
Registriert seit: 17.01.2006
Beiträge: 468
Slava
Standard

OT
ich habe meine erste Datenbanken-Erfahrungen mit Oracle gemacht und habe subquerys gerne verwendet. Erste Schok, dass ich bei entwicklung mit mysql 3 erlebt habe "Sch... subqueris gibt es gar nicht".
Ich habe ziemlich viele graue Hirnzellen verbrannt , bevor ich mich auf der join syntax umgestellt habe.
Jetzt pogrammiere ich etwa 5 Jahren PHP-Mysql und habe mich so stark an JOIN syntax angewönt, dass ich subquerys irgendwie vermeiden versuche.

und jetzt mal über Performance.
Was schneller ist kann nur BENCHMARK() zeigen, und es kann wohl sein, dass die Ergebnise von einer version zu anderer sich unterscheiden können.
jeder SQL ausdruk wird bei einer Datenbank-System durch ein parser gejagt, es kann wohl sein, dass ein subquery-syntax für der parser aufwendiger(ein paar 0.0001 sec) als join-syntax ist, aber am ende gibt es nur ein array mit zeigern auf die native datenbank-funktionen. Wenn dieser Array optimal aufgebaut ist, dann wird auch der Datenbank die bessere und schnellere Ergebnise liefern. Der SQL-Parser ändert sich aber auch von Version zur Version und es kann vorkommen, dass die Geschwindigkeit-unterschiede bei diesen 3 Abfragen bei nächster version überhaupt nicht mehr da sind.

und jetzt mal reale fakten
nach dem ich auf der console BENCHMARK() mit 10000000 wiederholungen gemacht habe, dann habe ich die Ergebnise bekommen, die ich eigentlich nicht erwartet habe
abfrage 1 (erste Platz) 1.16 sec
abfrage 3 (zweite Platz) 1.22 sec
abfrage 2( lol) 1.25 sec

edit: die tabelle ist aber klein, mit nur 56 einträgen, es muss natürlich bei den grösseren tabellen getestet werden.
mysql version 5.0.21
__________________
Slava
http://bituniverse.com
Slava ist offline   Mit Zitat antworten
Alt 23.03.2007, 00:51  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Nein du kannst die WHERE-Bedingung nicht in die ON-Bedingung schreiben. Denn die ON-Bedingung stellt nur fest, ob dieser Datensatz gejoint werden soll oder nicht. Dadurch multipliziert sich dein Ergebnis.

Ehrlich gesagt hat es mich überhaupt gewundert, dass man in WHERE-Bedingung Bezug auf den JOIN nehmen kann, ich habe das nur zufällig bei einem "Fehler" festgestellt (der dann keiner war).

Das mit dem Benchmark ist so eine Sache, wer weiß schon was für Prozesse in diesen 1.16 Sekunden noch nebenher laufen. Ein Status-Check vom Messanger und 50ms hängen am Ergebnis.
Wichtig für die Performance sind aber bestimmt auch die richtigen Indexe.
Aber besser kein Tipp als ein falscher! Darum betone ich nochmal, dass ich nur spekuliere, fundierte Kenntnisse in MySQL-Performance habe ich nicht. In Datenbank-Fachforen bist du da vielleicht besser beraten. Die Meisten hier sind ja lediglich Datenbank-Anwender.
Zergling-new ist offline   Mit Zitat antworten
Alt 23.03.2007, 00:57  
Erfahrener Benutzer
 
Registriert seit: 13.08.2007
Beiträge: 1.976
KingCrunch befindet sich auf einem aufstrebenden Ast
KingCrunch eine Nachricht über ICQ schicken KingCrunch eine Nachricht über AIM schicken KingCrunch eine Nachricht über MSN schicken KingCrunch eine Nachricht über Yahoo! schicken
Standard

Du triffst es: Im Endeffekt fliegt alles durch einen Parser. Und genau da find ichs "witzig". Der Parser übersetzt den Code ja in einen system-näheren Code. In einem Forum las ich, dass mein Beispiel 1 quasi gleichbedeutend ist mit dem Beispiel 2. So mal jetzt zum Beispiel Spannend ist jetzt, was relevant ist, was sich "pauschal" verbessern lässt, und was einfach so "schlecht" ist
__________________
Nicht jeder Fehler ist ein Bug.
KingCrunch ist offline   Mit Zitat antworten
Alt 23.03.2007, 02:05  
Erfahrener Benutzer
 
Registriert seit: 17.01.2006
Beiträge: 468
Slava
Standard

wenn ich aber ein Wahl zwischen Variante 1 und 2 habe, würde ich besser 2-te verwenden.
schon aus dem Grund, dass durch join die code eifach besser lesbar ist.
mann kann bei JOINS "visuel" besser ein Unterschied zwischen dem Tabellenverbund und Auswahl-bedingungen sehen.
Bei dem Verbienden von 2 tabellen ist diese Lesbarkeit vielleicht nicht so relevant, aber bei verbund von 4 oder 5 Tabellen wird es aber ziemlich schwer in einer langer Where -Bedingung richtige Tabellen-verbund zu finden.
Und da ich lediglich auch nur ein DB-Anwender bin, werde ich besser auf ein paar 0.0001 sekunden performance verzichten um mir bessere Lesbarkeit zu schaffen.

OT:
Jetzt bin ich selbst richtig verzweifelt .
kann sein, dass ich morgen alles zurück nehme und werde gegenteil behaupten
__________________
Slava
http://bituniverse.com
Slava ist offline   Mit Zitat antworten
Alt 23.03.2007, 02:50  
Erfahrener Benutzer
 
Registriert seit: 13.08.2007
Beiträge: 1.976
KingCrunch befindet sich auf einem aufstrebenden Ast
KingCrunch eine Nachricht über ICQ schicken KingCrunch eine Nachricht über AIM schicken KingCrunch eine Nachricht über MSN schicken KingCrunch eine Nachricht über Yahoo! schicken
Standard

OT: Möglicherweise

Der Witz ist ja, dass eine Abfrage über kleine Tabellen völlig gleichgültig ist, aber bei großen treten keine Differenzen jenseits von unter 0,0xsec auf
__________________
Nicht jeder Fehler ist ein Bug.
KingCrunch ist offline   Mit Zitat antworten
Alt 23.03.2007, 02:58  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Eigentlich sollte der Test ja sehr einfach zu machen sein.
Zwei Tabelle mit jeweils mehreren hunderttausend Einträgen anlegen und nochmal beides benchmarken, auch jeweils ein paar Millionen mal.

@Slava: Wie benchmarke ich denn ein komplettes Statement, meintest du SELECT BENCHMARK()? Die kannte ich garnicht und laut Manual gehen ja auch nur Ausdrücke?!
Zergling-new ist offline   Mit Zitat antworten
Alt 23.03.2007, 04:01  
Erfahrener Benutzer
 
Registriert seit: 17.01.2006
Beiträge: 468
Slava
Standard

select benchmark(anzahl_von_wiederholungen,'select feld from ....where subquerys...');

also das geht auch mit querys, aber ergebnis von query muss nur eine spalte und eine zeile liefern (nur 1 wert), sonnst funktioniert das nicht.
http://dev.mysql.com/doc/refman/5.1/...functions.html

mit PHPmyadmin geht das auch nicht,
also konsole benutzen.
ergebnis ist immer 0.
Aber nach der abfrage kommt meldung wieviele sekunden es gelaufen hat.

stell ruhig anzahl_von_wiederholungen auf 10000000
Slava ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Erledigt] Select über zwei Tabellen / Performanceproblem Wolla Datenbanken 20 15.06.2008 00:58
select mit inhalten aus mehreren Tabellen wurtzel Datenbanken 6 02.12.2006 17:37
SELECT aus 2 Tabellen jens21 Datenbanken 3 30.08.2006 00:54
[Erledigt] SELECT aus zwei "gleichen" Tabellen patr1k Datenbanken 2 05.07.2006 11:57
Select über zwei Tabellen danix-dj PHP Tipps 2006 11 22.05.2006 15:13
Select über 2 Tabellen MasterMind Datenbanken 11 08.04.2006 11:43
Select über mehrere tabellen Sclot Datenbanken 14 24.11.2005 16:56
[Erledigt] SELECT * FROM 2 Tabellen - Problem Datenbanken 1 01.09.2005 16:30
select über drei Tabellen Sonja PHP Tipps 2005 10 12.05.2005 14:27
SELECT über 4 Tabellen mit DISTINC PHP Tipps 2005 2 08.03.2005 19:50
Select mit 2 Tabellen Sonja PHP Tipps 2005 5 13.02.2005 12:49
mehrere tabellen verknüpfen bei select Datenbanken 3 29.09.2004 11:00
[Erledigt] INSERT INTO SELECT an mehrere Tabellen? Datenbanken 6 17.09.2004 16:57
[Erledigt] 2 mal select 1 form PHP-Fortgeschrittene 1 01.09.2004 20:13
[Erledigt] Join für Select Count(`id`)-Abfrage über 4 Tabellen Datenbanken 4 10.07.2004 18:32

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
oracle select mehrere tabellen, http://www.php.de/datenbanken/43763-select-ueber-zwei-tabellen.html, oracle abfrage über zwei tabellen, oracle select aus zwei tabellen, oracle select über mehrere tabellen, oracle select aus mehreren tabellen, oracle sql select 2 tabellen, oracle select zwei tabellen, oracle select von mehreren tabellen, oracle select aus 2 tabellen, select from über zwei tabellen performance, select zwei tabellen, oracle select 3 tabellen, abfrage über mehrere tabellen oracle, oracle select über zwei tabellen, oracle differenz, oracle sql select zwei tabellen, oracle select alle tabellen, select auf zwei tabellen, php oracle select join feldnamen gleich

Alle Zeitangaben in WEZ +1. Es ist jetzt 11:35 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.