Schrift
[thread]10845[/thread]

JOIN's und EXPLAIN



<< >> 5 Einträge, 1 Seite
pq
 2007-11-21 12:09
#102677 #102677
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
ein join ist komplexer als du denkst, und die datenbank intelligenter als du denkst.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
Froschpopo
 2007-11-20 23:42
#102689 #102689
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Habe folgende beide Statements.
Aufgabe: zeige alle User, die gerade online sind.
Code: (dl )
1
2
3
SELECT a.name FROM users a INNER JOIN sessions b ON a.name = b.name

SELECT b.name FROM sessions b INNER JOIN users b ON b.name = a.name


Die Tabellen sind das, was die Namen vermuten lassen.
"users" ist demnach viele tausend Datensätze groß, "sessions" nur weniger hundert.

Jetzt sagt mir mein Verstand, dass die erste Variante erstmal die große Datenbank durchläuft und nebenbei immer in sessions nachschaut.

Die zweite Variante hingegeben durchläuft dagegen zuerst die kleine und pickt sich dann nur die benötigten aus der großen Tabelle, was meinem Verstandes nach schneller sein müsste weil ja nicht die große Tabelle durchlaufen wird.

Ich verstehe jetzt aber folgendes nicht:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> EXPLAIN SELECT a.name FROM users a INNER JOIN sessions b ON a.name = b.name
+----+-------------+-------+--------+------------------+------------+---------+-----------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+------------------+------------+---------+-----------------+------+---------------------------------+
| 1 | SIMPLE | b | ALL | NULL | NULL | NULL | NULL | 8 | Using temporary; Using filesort |
| 1 | SIMPLE | a | eq_ref | PRIMARY | PRIMARY | 3 | users.b.user_id | 1 | Using where |
| 1 | SIMPLE | c | ref | usernummer,kombi | usernummer | 3 | users.a.id | 2 | Using index |
+----+-------------+-------+--------+------------------+------------+---------+-----------------+------+---------------------------------+
3 rows in set (0.00 sec)



mysql> EXPLAIN SELECT b.name FROM sessions a INNER JOIN users b ON a.name = b.name
+----+-------------+-------+--------+------------------+------------+---------+-----------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+------------------+------------+---------+-----------------+------+---------------------------------+
| 1 | SIMPLE | a | ALL | NULL | NULL | NULL | NULL | 7 | Using temporary; Using filesort |
| 1 | SIMPLE | b | eq_ref | PRIMARY | PRIMARY | 3 | users.a.user_id | 1 | Using where |
| 1 | SIMPLE | c | ref | usernummer,kombi | usernummer | 3 | users.a.user_id | 2 | Using index |
+----+-------------+-------+--------+------------------+------------+---------+-----------------+------+---------------------------------+
3 rows in set (0.00 sec)


Laut EXPLAIN gibt es ja tatsächlich keinen Unterschied zwischen den beiden Statements. Warum nicht?

Ich wollte eigentlich einen Beweis für meine Theorie, dass Variante 2 schneller ist, weil nur sessions durchlaufen wird. Variante 1 aber ist langsamer, weil users komplett durchlaufen wird.

Wo ist mein Denkfehler?
Froschpopo
 2007-11-21 13:03
#102700 #102700
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
bin schwer beeindruckt.
Froschpopo
 2007-11-21 17:29
#102740 #102740
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
kann man eigentlich diese Zeitaufzeichnung für den Query auch irgendwie abgreifen und später ausgeben oder muss man dafür benchmarks konstruieren?
Also quasi so wie ich ja FOUND_ROWS() auch abfragen kannn wäre es cool zu wissen wieviel Zeit so ein Query benötigt. Bisher habe ich immer das Statement in die Konsole kopiert, dort steht ja dann immer wieviele Sekunden es gedauert hat.
pq
 2007-11-21 17:36
#102741 #102741
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
bau in dein framework eine timing-funktion ein, mit CPAN:Time::HiRes
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
<< >> 5 Einträge, 1 Seite



View all threads created 2007-11-20 23:42.