Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]3577[/thread]

zuviele JOINs für mySQL



<< >> 7 Einträge, 1 Seite
Ronnie
 2005-05-27 19:50
#33307 #33307
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Hier mal ein Beispiel:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT people.ID_person, firstname, lastname, title, phone1, phone2, mail1, mail2, mobile, fax, comment
FROM people
JOIN belongs_to ON people.ID_person = belongs_to.ID_person
JOIN countries AS nationality ON belongs_to.ID_country = nationality.ID_country
JOIN has_regional_experience ON people.ID_person = has_regional_experience.ID_person
JOIN countries AS experience ON has_regional_experience.ID_country = experience.ID_country
JOIN owns ON people.ID_person = owns.ID_person
JOIN expertise ON owns.ID_expertise = expertise.ID_expertise
JOIN spoke ON people.ID_person = spoke.ID_person
JOIN languages ON spoke.ID_language = languages.ID_language
JOIN worked_for ON people.ID_person = worked_for.ID_person
JOIN donors ON worked_for.ID_donor = donors.ID_donor
WHERE nationality.country='Andorra'
GROUP BY people.ID_person

Diese Abfrage dauert ca. 2 Sekunden. Sie enthält 8 unnötige JOINs weil in der WHERE-clause nur die Nationalität gefragt ist. Ich bin davon ausgegangen das MySQL solche Anfragen optimiert und nur JOINs durchführt die auch benötigt werden.

Ich muss jetzt ein Stück Code entwerfen, das aus einem Webformular einen entsprechenden SQL-String baut. Sinnvollerweise werde ich mir dann anhand der übergebenen Parameter überlegen müssen, welche JOINs ich benötige und welche nicht.

Hattet ihr so ein Problem schonmal und wie habt ihr es gelöst?
GwenDragon
 2005-05-27 20:39
#33308 #33308
User since
2005-01-17
14748 Artikel
Admin1
[Homepage]
user image
Um welche MySQL-Version handelt es sich überhaupt?
Ronnie
 2005-05-27 21:16
#33309 #33309
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
[quote=GwenDragon,27.05.2005, 18:39]Um welche MySQL-Version handelt es sich überhaupt?[/quote]
Quote
ii mysql-server 4.0.24-5 mysql database server binaries
Ronnie
 2005-05-28 12:55
#33310 #33310
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Ich denke ich lass es jetzt erstmal so. Die Performance von meinem Mini-ITX Server ist eh nicht berauschend, also betrachte ich es mir auf dem Produktionssystem - wenn es akzeptabel ist, lasse ich es so.
Ronnie
 2005-05-29 18:34
#33311 #33311
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
      if (grep {$_ eq 'experience.country'} ($self->{field1}, $self->{field2}, $self->{field3})) {
$sqlquery .= q#
JOIN has_regional_experience ON people.ID_person = has_regional_experience.ID_person
JOIN countries AS experience ON has_regional_experience.ID_country = experience.ID_country
#;
}

if (grep {$_ eq 'nationality.country'} ($self->{field1}, $self->{field2}, $self->{field3})) {
$sqlquery .= q#
JOIN belongs_to ON people.ID_person = belongs_to.ID_person
JOIN countries AS nationality ON belongs_to.ID_country = nationality.ID_country
#;
}

if (grep {$_ eq 'expertise'} ($self->{field1}, $self->{field2}, $self->{field3})) {
$sqlquery .= q#
JOIN owns ON people.ID_person = owns.ID_person
JOIN expertise ON owns.ID_expertise = expertise.ID_expertise
#;
}

if (grep {$_ eq 'language'} ($self->{field1}, $self->{field2}, $self->{field3})) {
$sqlquery .= q#
JOIN spoke ON people.ID_person = spoke.ID_person
JOIN languages ON spoke.ID_language = languages.ID_language
#;
}

if (grep {$_ eq 'donor'} ($self->{field1}, $self->{field2}, $self->{field3})) {
$sqlquery .= q#
JOIN worked_for ON people.ID_person = worked_for.ID_person
JOIN donors ON worked_for.ID_donor = donors.ID_donor
#;
}

Okay, hier die Lösung zu meinem kleinen Problem. Wie sich herausstellte bringen die JOINs noch einen Seiteneffekt mit sich. Es handelt sich ja um eine m:n-Auflösung - ist aber n==0 - also existiert keine Zuordnung auf dieser Seite bekommt man auch keinen Datensatz von der Abfrage. Eigentlich logisch aber manchmal dauert es eben etwas länger.
renee
 2005-05-30 01:36
#33312 #33312
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Benutzt man dafür nicht OUTER JOIN??

Warum machst Du den Code eigentlich so umständlich??

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
my %sql = ('experience.country' =>  q#JOIN has_regional_experience ON people.ID_person = has_regional_experience.ID_person
JOIN countries AS experience ON has_regional_experience.ID_country = experience.ID_country
#,
'nationality.country' => q#JOIN belongs_to ON people.ID_person = belongs_to.ID_person
JOIN countries AS nationality ON belongs_to.ID_country = nationality.ID_country
#,
'expertise' => q#JOIN owns ON people.ID_person = owns.ID_person
JOIN expertise ON owns.ID_expertise = expertise.ID_expertise
#,
'language' => q#JOIN spoke ON people.ID_person = spoke.ID_person
JOIN languages ON spoke.ID_language = languages.ID_language
#,
'donor' => q# JOIN worked_for ON people.ID_person = worked_for.ID_person
JOIN donors ON worked_for.ID_donor = donors.ID_donor
#);

$sqlquery .= $sql{$self->{field1}}.$sql{$self->{field2}}.$sql{$self->{field3}}

ungetestet!
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Ronnie
 2005-05-30 04:03
#33313 #33313
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
[quote=renee,29.05.2005, 23:36]Warum machst Du den Code eigentlich so umständlich??[/quote]
Liegt am Wetter - das denken fällt mir schwerer. Deine Lösung hat aber den Nachteil, das wenn zweimal das selbe Kriterium ausgewählt wird, auch zweimal der selbe JOIN in den SQL-String eingebaut wird. Ich muss da wohl noch ein wenig rumprobieren ...
<< >> 7 Einträge, 1 Seite



View all threads created 2005-05-27 19:50.