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

SQL_CALC_FOUND_ROWS() (Seite 2)



<< |< 1 2 >| >> 19 Einträge, 2 Seiten
Froschpopo
 2007-05-14 13:15
#35479 #35479
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Es gibt einen ganz gewaltigen Unterschied zwischen
Code: (dl )
SELECT COUNT(id) FROM defaultusers


und dem hier:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
COUNT(a.id)

FROM defaultusers a

INNER JOIN photos b ON
b.id = (SELECT MAX(datestamp) FROM photos WHERE user_id = a.id)

INNER JOIN defaultusers c ON c.id = 39212

WHERE
a.status = 'N' and
a.sex = 'w' and
YEAR(CURDATE())-YEAR(a.birthday) <= 30 and
YEAR(CURDATE())-YEAR(a.birthday) >= 16 and
(ACOS((SIN(RADIANS(c.lat))*SIN(RADIANS(a.lat))) + (COS(RADIANS(c.lat))*COS(RADIANS(a.lat))*COS(RADIANS(a.lon)-RADIANS(c.lon)))) * 6378.388) <= 50

ORDER BY a.lastlogin DESC
LIMIT 0,10;

nur letzterer liefert exakt die anzahl der zu suchergebnisse die auf die ergebnistabelle passt.
deiner zählt die ganze defaultusers-datenbank und liefert zählt deshalb fast 40.000 zu viel ;)\n\n

<!--EDIT|Froschpopo|1179135212-->
pq
 2007-05-14 13:35
#35480 #35480
User since
2003-08-04
12209 Artikel
Admin1
[Homepage]
user image
[quote=Froschpopo,14.05.2007, 11:09]
Quote
was genau willst du denn zählen? wenn du die daten aus der anderen
tabelle für die anzahl nicht brauchst, dann lass sie halt raus."

Ich brauche die Anzahl der Ergebnisse von defaultusers, damit ich später angeben kann, auf wieviel HTML-Seiten die Ergebnistabelle verteilt wird.[/quote]
[sql]SELECT count(*) from defaultusers[/sql]
ja, ich weiss, dass du das nicht willst, aber dann sag halt etwas genauer, *was* du willst!
wenn ich frage, was du zählen willst, dann will ich wissen, ob du exakt
denselben join brauchst oder nicht.
und wenn ja, dann ist es halt so. es wird nicht schneller
gehn. cache die daten halt. du wirst doch nicht alle zahlen für jeden user
bei jedem request brauchen.
Quote
hab ich ja gemacht.

und warum sagtest du das nicht?
Quote
Der Code dauert mit zwei Statements fast solang, wie nur eines mit SQL_CALC_FOUND_ROWS. Es kommt fast dasselbe dabei raus.

fast solang? das ist ja sogar besser. fast dasselbe? das hört sich sehr
vage an. vielleicht solltest du das erstmal reparieren.
Quote
Zum Thema trivial: Das ist nicht möglich, da ich vor dem LEFT JOIn die ID-Primärschlüssel noch nicht kenne.

das ist mir schon klar. ich habe doch nur erklärt, was ein einfacher join
ist und wo die datenbank etwas mehr rechnen muss.
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-05-14 13:42
#35481 #35481
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
das hab ich doch alles schonmal gesagt. Ich möchte wissen, wieviele Suchergebnisse diese Abfrage liefert:
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
SELECT
b.id AS file_id,
a.id,
a.name,
IF(sessions.userid IS NOT NULL, '1','0') AS status

FROM defaultusers a

LEFT JOIN sessions ON
a.id = sessions.userid

INNER JOIN photos b ON
b.id = (SELECT MAX(datestamp) FROM photos WHERE user_id = a.id)

INNER JOIN defaultusers c ON c.id = 39212

WHERE
a.status = 'N' and
a.sex = 'w' and
YEAR(CURDATE())-YEAR(a.birthday) <= 30 and
YEAR(CURDATE())-YEAR(a.birthday) >= 16 and
(ACOS((SIN(RADIANS(c.lat))*SIN(RADIANS(a.lat))) + (COS(RADIANS(c.lat))*COS(RADIANS(a.lat))*COS(RADIANS(a.lon)-RADIANS(c.lon)))) * 6378.388) <= 50

ORDER BY a.lastlogin DESC
LIMIT 0,10;


Das kann ich ohne SQL_CALC_FOUND_ROWS nur herausbekommen, wenn ich dieselbe Abfrage mache, nur mit einem COUNT(), anstatt eine Ergebnistabelle zu erstellen.

Das geht nur so:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
COUNT(a.id)

FROM defaultusers a

INNER JOIN photos b ON
b.id = (SELECT MAX(datestamp) FROM photos WHERE user_id = a.id)

INNER JOIN defaultusers c ON c.id = 39212

WHERE
a.status = 'N' and
a.sex = 'w' and
YEAR(CURDATE())-YEAR(a.birthday) <= 30 and
YEAR(CURDATE())-YEAR(a.birthday) >= 16 and
(ACOS((SIN(RADIANS(c.lat))*SIN(RADIANS(a.lat))) + (COS(RADIANS(c.lat))*COS(RADIANS(a.lat))*COS(RADIANS(a.lon)-RADIANS(c.lon)))) * 6378.388) <= 50

ORDER BY a.lastlogin DESC
LIMIT 0,10;

daran dürfte es eigentlich nichts zu rütteln geben ;)

Cachen kann ich die Daten nur mit erheblich großem Aufwand, denn zwischenzeitlich kann sich "photos" auch schon wieder geändert haben, Stichwort: "Bad Links"

"Fast so lang" bedeutet immerhin noch 14 Sekunden und das ist einfach zu lang.\n\n

<!--EDIT|Froschpopo|1179135801-->
renee
 2007-05-14 14:14
#35482 #35482
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Warum nimmst Du dann nicht eine extra Tabelle, in der Du die Anzahl von gewissen Abfragen speicherst? Du musst dann halt in den Funktionen, wo jemand Bilder hochladen bzw. löschen kann, die Anzahl anpassen.
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/
pq
 2007-05-14 14:23
#35483 #35483
User since
2003-08-04
12209 Artikel
Admin1
[Homepage]
user image
wenn du nicht cachen kannst und dir die abfrage zu lange dauert, dann hast du eben
pech gehabt. im übrigen glaube ich nicht, dass das cachen so ein grosser aufwand ist.
du weisst vermutlich nur nicht, wie...
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-05-14 14:27
#35484 #35484
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
das ist technisch ebenfalls unmöglich.
Beispiel:

Kunde 30 hat folgenden EIntrag in Abfrage-Tabelle:
Code: (dl )
1
2
3
4
user_id|found_users
30 323922
31 293
40 3928382

Durchschnittlich melden sich pro Stunde 2 User wieder ab.
Woher weiss ich, bei welchem User die found_users -Spalte neu berechnet werden muss?
Froschpopo
 2007-05-14 14:33
#35485 #35485
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
[quote=pq,14.05.2007, 12:23]wenn du nicht cachen kannst und dir die abfrage zu lange dauert, dann hast du eben
pech gehabt. im übrigen glaube ich nicht, dass das cachen so ein grosser aufwand ist.
du weisst vermutlich nur nicht, wie...[/quote]
Soll ich 30.00 Datensätze pro User in einen Cache einlesen?
Das wäre doch voll Speichermord wenn nur 100 Leute eine Cache-Session besitzen.
30.000 Ergebnisse sind ja schon arg wenige.
Aber ich freu mich natürlich über jeden Vorschlag.
Hab mir auch grad schon SQL_CACHE angeschaut:
http://dev.mysql.com/doc/refman/5.1/de/query-cache-how.html
Aber da wird scheinbar nur im Arbeitsspeicher gechached.\n\n

<!--EDIT|Froschpopo|1179139213-->
pq
 2007-05-14 15:49
#35486 #35486
User since
2003-08-04
12209 Artikel
Admin1
[Homepage]
user image
sag ich doch, du weisst nur nicht, wie.
ich kann dir nicht sagen, wie du cachen musst, da ich nicht weiss, welche daten
du wann brauchst. was ich aber schonmal sagte, ist, dass du bestimmt nicht bei
jedem request den count von jedem user brauchst. cache pro user den
count und erneuere den cache regelmaessig.
es reicht schon ein simples speichern der zahlen auf der platte. so mache ich das
im prinzip beim poard, so wird die startseite und die letzten 24 stunden gecached.
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-05-14 16:04
#35487 #35487
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Die Suchergebnisse der User sind unterschiedlich.
Jeder Suchquery ist quasi anders.
Denk-Beispiel:

Schritt 1: Ein User sucht andere User zwischen 18 und 24 Jahren.
Schritt 2:FOUND_ROWS() wird gecached.
Schritt 3: Ein anderer User, der 19 Jahre alt ist, löscht seinen Profil-Datensatz.
Schritt 4: In der zwischenzeit haben sich zwei neue User angemeldet die auch noch auftauchen müssen

Wie du siehst ist das unglaublich komplex.
<< |< 1 2 >| >> 19 Einträge, 2 Seiten



View all threads created 2007-05-13 21:14.