chrisfah
Goto Top

Vereinfachung und Beschleunigung einer Mysql Abfrage

Ich suche eine resourcensparende Version der folgenden Abfrage

Hallo Leute,

wieder einaml wende ich mich vertrauensvoll und hilfesuchend an euch!

Ich habe eine Mysql Query, die aus zwei Teilen besteht. Einzeln sind diese Abfragen relativ rasch, in Kombination jedoch sind sie extrem langsam und gehen nahezu an das Zeillimit, von der CPU Auslastung ganz zu schweigen....
Einzelne Queries:
$inter_q_r2 = "SELECT DISTINCT i.i_id, i.vorname, i.nachname, i.adresse, i.plz, i.ort, i.land, DATE_FORMAT(i.i_erstellt, '%d. %m. %Y') as datum    
				FROM ".TABLE_INTERESSENTEN." i, ".TABLE_OBJEKT2MAKLER." o2m, ".TABLE_KONTAKTE." k   
				WHERE o2m.u_id = '".(int)$_SESSION['u_id']."'   
				AND o2m.chief_agent = '1'   
				AND k.objekt_id = o2m.o_id 
				AND i.i_id = k.interessenten_id 
				AND i.i_system_status = '1'   
				AND i.i_status = '1'  
				ORDER BY i.nachname ASC, i.vorname ASC, i.plz ASC ";  
$inter_q_r2 = "SELECT DISTINCT i.i_id, i.vorname, i.nachname, i.adresse, i.plz, i.ort, i.land, DATE_FORMAT(i.i_erstellt, '%d. %m. %Y') as datum    
				FROM ".TABLE_INTERESSENTEN." i   
				WHERE i.firmen_id = '".(int)$_SESSION['firmen_id']."'  
				AND i.i_system_status = '1'   
				AND i.i_status = '1'  
				ORDER BY i.nachname ASC, i.vorname ASC, i.plz ASC ";  

Kann mmir jemand helfen, diese beiden Queries in einer gemeinsamen zu optimieren!?!?
Bisher sieht es bei mir so aus, ist aber extrem langsam...
$inter_q_r2 = "SELECT DISTINCT i.i_id, i.vorname, i.nachname, i.adresse, i.plz, i.ort, i.land, DATE_FORMAT(i.i_erstellt, '%d. %m. %Y') as datum    
				FROM ".TABLE_INTERESSENTEN." i, ".TABLE_OBJEKT2MAKLER." o2m, ".TABLE_KONTAKTE." k   
				WHERE o2m.u_id = '".(int)$_SESSION['u_id']."'   
				AND o2m.chief_agent = '1'   
				AND k.objekt_id = o2m.o_id 
				AND i.i_id = k.interessenten_id 
				OR (i.firmen_id = '".(int)$_SESSION['firmen_id']."')   
				AND i.i_system_status = '1'   
				AND i.i_status = '1'  
				ORDER BY i.nachname ASC, i.vorname ASC, i.plz ASC ";  

Wie gesagt, die beiden Teilqueries einzeln gehen rasch, zusammen sind sie elends langsam....

Lg, Chris

Content-Key: 172023

Url: https://administrator.de/contentid/172023

Printed on: April 23, 2024 at 11:04 o'clock

Member: nxclass
nxclass Aug 24, 2011 at 22:04:40 (UTC)
Goto Top
... ich sehe nur eine Query !? - evtl. mal JOIN benutzen und über die Spalten in ON einen Index setzen.
Member: pi314
pi314 Aug 28, 2011 at 11:24:47 (UTC)
Goto Top
Hi,

was heißt "in Kombination"?
Hängst du die mit "union all" oder "union" zusammen?


Gruß,
pi314
Member: nxclass
nxclass Aug 28, 2011 at 13:18:48 (UTC)
Goto Top
SELECT
	i.vorname,
	i.nachname,
	i.adresse,
	i.plz,
	i.ort,
	i.land,
	DATE_FORMAT(i.i_erstellt, '%d. %m. %Y') as datum  
FROM
	".TABLE_KONTAKTE." k  
		LEFT JOIN ".TABLE_INTERESSENTEN." i ON ( i.i_id = k.interessenten_id )  
		LEFT JOIN ".TABLE_OBJEKT2MAKLER." o2m ON ( o2m.o_id = k.objekt_id )  
WHERE
	i.i_system_status = '1' AND  
	i.i_status = '1' AND (  
		(
			o2m.u_id = '".(int)$_SESSION['u_id']."'	AND  
			o2m.chief_agent = '1'  
		) OR (
			i.firmen_id = '".(int)$_SESSION['firmen_id']."'  
		)
	)
ORDER BY
	i.nachname,
	i.vorname,
	i.plz
;

Index über:
i.i_id
k.interessenten_id
k.objekt_id
o2m.o_id

...ob die Abfrage nun das richtige zurück gibt musst Du testen.
Member: Biber
Biber Aug 28, 2011 at 13:30:02 (UTC)
Goto Top
Moin nxclass,

aber ich denke, ein UNION über die zwei (funktionierenden) Queries geht schneller als irgendeine beliebige Query mit "OR".

Select x.* from (
 SELECT DISTINCT i.i_id, i.vorname, i.nachname, i.adresse, i.plz, i.ort, 
                i.land, DATE_FORMAT(i.i_erstellt, '%d. %m. %Y') as datum  
                FROM ".TABLE_INTERESSENTEN." i, ".TABLE_OBJEKT2MAKLER." o2m, ".TABLE_KONTAKTE." k   
		WHERE o2m.u_id = '".(int)$_SESSION['u_id']."'   
		AND o2m.chief_agent = '1'   
		AND k.objekt_id = o2m.o_id 
		AND i.i_id = k.interessenten_id 
		AND i.i_system_status = '1'   
		AND i.i_status = '1'  
UNION
 SELECT DISTINCT i.i_id, i.vorname, i.nachname, i.adresse, i.plz, i.ort, i.land, DATE_FORMAT(i.i_erstellt, '%d. %m. %Y') as datum    
 		FROM ".TABLE_INTERESSENTEN." i   
 		WHERE i.firmen_id = '".(int)$_SESSION['firmen_id']."'  
 		AND i.i_system_status = '1'   
 		AND i.i_status = '1'  
		
) x
ORDER BY x.nachname ASC, x.vorname ASC, x.plz ASC

P.S. Wenn in den bisherigen Queries ein DISTINCT nötig ist, dann ist aber die Struktur marode.
Kommen denn wirklich ohne DISTINCT doppelte Sätze heraus?

Grüße
Biber
Member: ChrisFah
ChrisFah Aug 28, 2011 at 13:34:51 (UTC)
Goto Top
Hallo,

die erste und die zweite Query vom meinem obersten Post zusammengefasst ergibt die dritte, sehr langsame Query.

lg, Chris
Member: nxclass
nxclass Aug 28, 2011 at 18:23:40 (UTC)
Goto Top
in diesem Fall würde ich aber empfehlen statt 2x
 		AND i.i_system_status = '1'   
 		AND i.i_status = '1'  
auszuführen, schon vor dem Union die Daten mit diesen WHERE Bedingungen zu reduzieren. Zum Beispiel mit einem View, Unterabfrage oder temp. Tabelle.

Das
DISTINCT i.i_id
ist in dem 2. Teil der Abfrage wohl überflüssig, da i.i_id sicherlich ein eindeutiger Wert ist !?
Member: Biber
Biber Aug 28, 2011 at 19:08:30 (UTC)
Goto Top
Moin nxclass,

ist natürlich alles Spekulation.
Wenn in der WHERE-Bedingung beispielsweise eine Zeitraum-Einschränkung stünde ("nur die Sätze vom 1.7.2011 bis 31.7.2011")...
--> dann würde ich von einer wesentlichen Reduzierung aller Sätze ausgehen.

Bei Feldern, die den Verlegenheitsnamen "status" und "system_status" haben, gehe ich durch leidvolle Erfahrung eher davon aus, dass 98% aller Sätze durch diese Maschen schlüpfen.
Ist aber nur ein Verdacht.

Mit der 2.Distinct-Bedingung hast du aber sicherlich Recht.

Das zweite DISTINCT kann in meinem UNION rausfliegen, unabhängig davon kann auch aus dem UNION ein UNION ALL werden.
Dann spare ich noch einen zeitaufwändigen SORT-Vorgang und bin erst recht schneller als du face-wink

Grüße
Biber
Member: ChrisFah
ChrisFah Aug 28, 2011 at 21:29:13 (UTC)
Goto Top
So liebe Leute,

ich habs jetzt so gelöst, wie der Biber es vorgeschlagen hat.
Mit UNION ALL und die beiden DISTINCT sind wirklich überflüssig gewesen (eine Altlast von ner anderen Query Version).
Und es fetzt nur so ab !!!!
SUPER !!!

Vielen Dank euch allen !!!

lg, Chris