[MySQL] Random in subquery erg traag

Pagina: 1
Acties:
  • 217 views sinds 30-01-2008
  • Reageer

  • wcduck
  • Registratie: September 2000
  • Niet online
Hallo allemaal,

ik heb een traagheidsprobleempje bij een query. Momenteel duurt het 27 sec voordat de query is uitgevoerd. Het betreft deze query:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
SELECT   naam,
    MONTH(datum) AS maand,
    COUNT( * ) AS aantal 
    FROM tabelnaam 
    WHERE YEAR(datum) = YEAR(NOW())
    AND naam = (
        SELECT naam 
        FROM tabelnaam
        WHERE MONTH(datum) = MONTH(NOW()) 
        ORDER BY RAND()
        LIMIT 0,1)
GROUP BY maand

Wanneer ik de twee queries apart van elkaar uitvoer zijn ze gewoon snel. Gecombineerd in één query is het niet vooruit te branden. Weet één van jullie een snellere oplossing voor deze query? Het zit hem vooral in het opvragen van een random naam uit de database. Let wel: er zijn geen id's gekoppeld aan de namen. Trucjes als in B-Man in "[MySQL 4.1] order by rand() is traag" werken dan ook niet.

Alvast bedankt.

[ Voor 6% gewijzigd door RobIII op 12-06-2007 13:59 . Reden: Code tags toegevoegd ]

I don't suffer from insanity, I enjoy every minute of it.


  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24

BikkelZ

CMD+Z

Kun je die RAND() naam niet aan de buitenkant doen en de rest in de subquery proppen? Aangezien je RAND in een subquery hebt, gaat hij ook iedere keer weer opnieuw die hele subquery uitvoeren bij iedere rij van de query waar de subquery in zit, terwijl je met de RAND aan de buitenkant een constante subquery hebt misschien.

iOS developer


  • momania
  • Registratie: Mei 2000
  • Laatst online: 30-11 19:29

momania

iPhone 30! Bam!

waarom doe je niet een group by op maand en naam, dan heb je die hele sub query volgens mij niet eens nodig ;)

SQL:
1
2
3
4
5
6
7
8
SELECT naam,
MONTH(datum) AS maand,
COUNT( * ) AS aantal
FROM tabelnaam
WHERE YEAR(datum) = YEAR(NOW())
GROUP BY maand, naam
ORDER BY RAND()
LIMIT 0,1

[ Voor 44% gewijzigd door momania op 11-06-2007 23:29 ]

Neem je whisky mee, is het te weinig... *zucht*


  • wcduck
  • Registratie: September 2000
  • Niet online
Momania, dat zou betekenen dat ik maar één waarde terug krijg. Ik wil juist meerdere waarden terugkrijgen, maar met het filteren op één naam. In ieder geval bedankt voor het meedenken!!

BikkelZ, de rand() aan de buitenkant zal vanwege de bovenstaande reden niet werken. Nog bedankt voor het geven van een uitleg. Ik wist namelijk niet dat hij de subquery meerdere malen uitvoerde. Weer wat geleerd.

Wellicht helpt het wanneer ik uitleg wat ik ermee wil doen:
ik wil het aantal berichten
- per maand
- van dit jaar
- van een random persoon die deze maand van dit jaar op een forum heeft
Momenteel verwerk ik het in PHP door middel van twee query's achter elkaar. Opzich geen probleem, maar toch blijft het aan me vreten, want het moet toch beter kunnen.

I don't suffer from insanity, I enjoy every minute of it.


  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24

BikkelZ

CMD+Z

Een SQL optimizer (zit in iedere SQL DB) kijkt altijd of hij een constante result set haalt uit een subquery. Lijkt het er op dat dat niet zo is dan voert hij hem voor de zekerheid maar iedere keer uit, niet altijd terecht.

Volgens mij kun je nog steeds vanaf 'buiten' JOINen. Pseudo:

SQL:
1
2
3
4
5
6
SELECT naam, stats.*
FROM users
JOIN (SELECT naam plus al je statistieken) as stats ON users.naam = stats.naam
WHERE naam IN (SELECT naam FROM deze maand)
ORDER BY RAND()
LIMIT 1


Dus je stats worden gewoon een tijdelijke een tussentabel. Query en subquery wordt maar een keer uitgevoerd. Kijk even of dit werkt, ben wel benieuwd, ik doe zelf niet zo veel met RAND().

[ Voor 6% gewijzigd door BikkelZ op 12-06-2007 13:55 ]

iOS developer


  • REDFISH
  • Registratie: Augustus 2001
  • Laatst online: 20-11-2024

REDFISH

beetje vreemd en niet lekker

wcduck schreef op dinsdag 12 juni 2007 @ 13:05:
Momania, dat zou betekenen dat ik maar één waarde terug krijg. Ik wil juist meerdere waarden terugkrijgen, maar met het filteren op één naam. In ieder geval bedankt voor het meedenken!!

Wellicht helpt het wanneer ik uitleg wat ik ermee wil doen:
ik wil het aantal berichten
- per maand
- van dit jaar
- van een random persoon die deze maand van dit jaar op een forum heeft
gepost? geregistreerd?

Je wilt toch alle statistieken voor die ene persoon die random is bepaald?

Anders een lelijke oplossing:
pleur de naam die de SELECT met RAND geeft in een dummy tabel en haal die dan in de subselect 1 maal op.

Ik denk dat er nu iets niet helemaal goed gaat bij de subselect met die RAND

Volgens mij geeft de subselect voor elke rij van het hoofdselect door die RAND juist elke keer een andere naam door. Dit wil je niet hebben.

Het is net als met elke programmeertaal, als je iets wil vergelijken met iets anders dat random wordt bepaald dan moet je dit random iets eerst vastleggen.

@Bikkelz, is er wel iets te joinen hier ? het lijkt erop dat de gegevens uit 1 tabel komen (ik zag namelijk twee keer 'naam' staan)

Probeer het anders eens met HAVING? Je maakt dan eerst een tabel (voor posts van dit jaar)met
-naam
-maand
-aantal van die maand

en je limiteert dan de uitvoer van de hele tabel tot de uitvoer met een bepaalde naam

Ik denk dat dit ook is wat eerder bedoeld werd met het naar buiten halen van de RAND.

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
 SELECT naam, 
 MONTH(datum) AS maand, 
 COUNT( * ) AS aantal  
 FROM tabelnaam  
 WHERE YEAR(datum) = YEAR(NOW()) 
   
 GROUP BY maand 
 HAVING NAAM = (SELECT naam 
           FROM tabelnaam
           WHERE MONTH(datum) = MONTH(NOW())
           ORDER BY RAND()
           LIMIT 0,1)


Ik kan het zelf helaas niet controleren want ik gebruik hier Interbase, maar ik vermoed dat dit vrijwel zeker moet werken, dus laat het even weten aub.
Zo en nu is het laat genoeg geworden.

[ Voor 170% gewijzigd door REDFISH op 13-06-2007 11:02 ]


  • wcduck
  • Registratie: September 2000
  • Niet online
Bedankt allemaal voor het meedenken. Het is echter nog steeds niet gelukt. De oplossing van Redfish geeft een merkwaardig resultaat: af en toe krijg ik een uitkomst met maar één maand, en af en toe krijg ik ook helemaal geen resultaat. Blijkbaar is HAVING niet de oplossing.

I don't suffer from insanity, I enjoy every minute of it.


  • CrashOne
  • Registratie: Juli 2000
  • Niet online

CrashOne

oOoOoOoOoOoOoOoOoOo

Als ze los beide snel zijn, dan voer je ze toch lost uit?
Zet de waarde van de sub-query in een var en gooi die in je tweede, klaar toch?

Of is dit in jou situatie niet mogelijk?

Huur mij in als freelance SEO consultant!

Pagina: 1