Hallo,
De volgende query duurt ongeveer 2,5 seconde om uit te voeren. Dit zou ik graag willen optimaliseren, maar hierbij loop ik vast.
Tabel contactpersonen: Een lijst met gebruikers.PHP Code:
SELECT
// enkele velden van de contactgegevens tabel
FROM
contactpersonen AS c
LEFT JOIN
(SELECT * FROM `contactgegevens` WHERE `status` != '9' ORDER BY `id` DESC) as `cg`
ON cg.contact_id = c.id
WHERE
// enkele voorwaarden waaraan de contactgegevens moeten voldoen
GROUP BY
c.id
Tabel contactgegevens: Een lijst van alle contactgegevens per gebruiker. Bij wijziging wordt er een nieuwe record toegevoegd in plaats van de bestaande gewijzigd om hiermee een geschiedenis op te bouwen.
Het probleem is dat de LEFT JOIN subquery alle contactgegevens erbij pakt, in plaats van de gegevens die behoren bij de contactpersoon.
Het uiteindelijke resultaat is dus goed, maar de query duurt te lang om uit te voeren. Hopelijk kunnen jullie hiermee helpen.
Groet.
- Complexe MySQL query
-
23-09-2015, 15:27 #1
- Berichten
- 71
- Lid sinds
- 17 Jaar
Complexe MySQL query
-
23-09-2015, 15:33 #2
- Berichten
- 1.215
- Lid sinds
- 17 Jaar
Re: Complexe MySQL query
Wat is de grote van de database en tabellen?
-
23-09-2015, 15:37 #3
- Berichten
- 71
- Lid sinds
- 17 Jaar
Re: Complexe MySQL query
Bedankt voor je reactie.
contactpersonen
contactgegevens1,070 InnoDB utf8_unicode_ci 96KiB Heb je nog meer info nodig?1,803 InnoDB utf8_unicode_ci 352KiB
Nog even ter aanvulling. Van de contactpersonen die hij moet laten zien, moet de query dus de laatste rij met contactgegevens gebruiken. Vandaar de ORDER BY in de subquery van de left join
-
23-09-2015, 15:43 #4
- Berichten
- 1.215
- Lid sinds
- 17 Jaar
Re: Complexe MySQL query
SELECT
// enkele velden van de contactgegevens tabel
FROM
contactpersonen AS c
LEFT JOIN contactgegevens as cg ON cg.contact_id = c.id
WHERE
cg.`status` != '9'
// enkele voorwaarden waaraan de contactgegevens moeten voldoen
ORDER BY previos_condition
GROUP BY
c.id
Probeer dit eens
-
23-09-2015, 15:46 #5
- Berichten
- 71
- Lid sinds
- 17 Jaar
Re: Complexe MySQL query
SELECT
// enkele velden van de contactgegevens tabel
FROM
contactpersonen AS c
LEFT JOIN contactgegevens as cg ON cg.contact_id = c.id
WHERE
cg.`status` != '9'
// enkele voorwaarden waaraan de contactgegevens moeten voldoen
ORDER BY previos_condition
GROUP BY
c.id
Probeer dit eens
Alvast bedankt!
-
23-09-2015, 15:49 #6
- Berichten
- 1.215
- Lid sinds
- 17 Jaar
Re: Complexe MySQL query
Dat is jou voorwaarde die je eerder had gesteld
-
23-09-2015, 15:55 #7
- Berichten
- 71
- Lid sinds
- 17 Jaar
-
23-09-2015, 16:12 #8
- Berichten
- 71
- Lid sinds
- 17 Jaar
Re: Complexe MySQL query
Helaas heeft dit niet geholpen. Het is in MySQL niet mogelijk om te sorteren op de LEFT JOIN, daarvoor had ik die subquery gemaakt.
-
23-09-2015, 16:14 #9
- Berichten
- 1.215
- Lid sinds
- 17 Jaar
-
23-09-2015, 16:24 #10
- Berichten
- 71
- Lid sinds
- 17 Jaar
Re: Complexe MySQL query
PHP Code:(SELECT * FROM `contactgegevens` WHERE `status` != '9' ORDER BY `id` DESC) as `cg`
Nu het sterretje is vervangen door de benodigde velden, blijft er nog een laadtijd over van 0.9 sec.
Mocht iemand nog meer tips hebben dan hoor ik het graag. (Geen idee of hier echte SQL goeroes op dit forum zitten)
-
23-09-2015, 16:30 #11
- Berichten
- 301
- Lid sinds
- 17 Jaar
Re: Complexe MySQL query
Heb je je indexes op orde?
-
23-09-2015, 17:26 #12
64BitsWebhosting.EU
- Berichten
- 2.085
- Lid sinds
- 18 Jaar
Re: Complexe MySQL query
De query is niet complex, maar gewoon van nature traag.
- in je subquery gebruik een descending order zonder limit (uiteraard), maar hierdoor moet wel de index voor elke contactpersoon helemaal opnieuw doorlopen worden.
- daardoor is er ook geen optimalisatie van je subquery mogelijk
- je gebruikt een != 9, dat is per definitie niet te optimaliseren
Hierdoor ben je dus 1070 * 1803 records aan het verwerken terwijl je er maar 1070 + 1070 nodig hebt.
Als je nu een veldje 'laatste' erbij zet en elke keer als je een contactgegeven toevoegt hier het veldje 'laatste' op 1 zet en bij het vorige van die persoon het 'laatste' veldje op 0 zet, dan hoef je alleen een de index op contactgegevens 'contact_id' uit te breiden met het 'laatste' veld om het zo snel mogelijk te hebben.
SELECT
// enkele velden van de contactgegevens tabel
FROM
contactpersonen c, contactgegevens cg WHERE c.id = cg.contact_id and cg.laatste != '1'
and // andere voorwaarden waaraan de contactgegevens moeten voldoen
-
23-09-2015, 17:43 #13
- Berichten
- 71
- Lid sinds
- 17 Jaar
Re: Complexe MySQL query
Ja, bedankt voor je reactie!
De query is niet complex, maar gewoon van nature traag.
- in je subquery gebruik een descending order zonder limit (uiteraard), maar hierdoor moet wel de index voor elke contactpersoon helemaal opnieuw doorlopen worden.
- daardoor is er ook geen optimalisatie van je subquery mogelijk
- je gebruikt een != 9, dat is per definitie niet te optimaliseren
Hierdoor ben je dus 1070 * 1803 records aan het verwerken terwijl je er maar 1070 + 1070 nodig hebt.
Als je nu een veldje 'laatste' erbij zet en elke keer als je een contactgegeven toevoegt hier het veldje 'laatste' op 1 zet en bij het vorige van die persoon het 'laatste' veldje op 0 zet, dan hoef je alleen een de index op contactgegevens 'contact_id' uit te breiden met het 'laatste' veld om het zo snel mogelijk te hebben.
SELECT
// enkele velden van de contactgegevens tabel
FROM
contactpersonen c, contactgegevens cg WHERE c.id = cg.contact_id and cg.laatste != '1'
and // andere voorwaarden waaraan de contactgegevens moeten voldoen
Dit is na de voorgaande wijzigingen nog precies waar de schoen wringt. Ik gebruikte status != 9 om de laatste te pakken, nu blijkt dat dit niet de juiste status is waardoor de query inderdaad alsnog langs alle records ging.
Een nieuwe test met de juiste status geeft een snelheid van 0.6 sec.
Zou het nog sneller kunnen?
Edit: het zoeken bij de WHERE werkt natuurlijk ook niet meer op de oude gegevens, ik ga nog even bedenken of dit nodig is.
Edit 2: Eerder genoemde snelheden waren met SQL_NO_CACHE, om de daadwerkelijke snelheid te zien.Laatst aangepast door N P : 23-09-2015 om 17:51 Reden: toevoegingen
-
23-09-2015, 18:11 #14
- Berichten
- 1.410
- Lid sinds
- 16 Jaar
Re: Complexe MySQL query
Zoals Mark zei, welke indexes heb je ingesteld? Dat is meestal iets waar je erg veel winst kunt krijgen.
-
23-09-2015, 18:24 #15
64BitsWebhosting.EU
- Berichten
- 2.085
- Lid sinds
- 18 Jaar
Re: Complexe MySQL query
Ja, bedankt voor je reactie!
Bedankt voor je reactie John!
Dit is na de voorgaande wijzigingen nog precies waar de schoen wringt. Ik gebruikte status != 9 om de laatste te pakken, nu blijkt dat dit niet de juiste status is waardoor de query inderdaad alsnog langs alle records ging.
Een nieuwe test met de juiste status geeft een snelheid van 0.6 sec.
Zou het nog sneller kunnen?
Edit: het zoeken bij de WHERE werkt natuurlijk ook niet meer op de oude gegevens, ik ga nog even bedenken of dit nodig is.
Edit 2: Eerder genoemde snelheden waren met SQL_NO_CACHE, om de daadwerkelijke snelheid te zien.
Zet maar eens 'explain' of 'explain extended' voor je select als je hem in phpmyadmin uitvoert.
Dat helpt vaak wel om de juiste indexen te maken/kiezen of bij het herschrijven van je query.
In mijn voorbeeldquery moest trouwens 'laatste = 1' in de query staan, niet '!= 1'... :)
Plaats een
- + Advertentie
- + Onderwerp
Marktplaats
Webmasterforum
- Websites algemeen
- Sitechecks
- Marketing
- Domeinen algemeen
- Waardebepaling
- CMS
- Wordpress
- Joomla
- Magento
- Google algemeen
- SEO
- Analytics
- Adsense
- Adwords
- HTML / XHTML
- CSS
- Programmeren
- PHP
- Javascript
- JQuery
- MySQL
- Ondernemen algemeen
- Belastingen
- Juridisch
- Grafisch ontwerp
- Hosting Algemeen
- Hardware Info
- Offtopic