Ik heb een webapplicatie waarin inderzoeksgegevens naartoe worden geupload. Deze worden opgeslagen in een MySQL database waarna er allemaal spannende dingen mee gedaan kunnen worden. Onderdeel van het upload-process is een bestand met de daadwerkelijke gegevens, een tab-seperated textfile. Deze lees ik regel voor regel uit in PHP, na controle en wat conversies sla ik elke regel op een array $DataColumnsInsert. Vervolgens bouw ik op de volgende manier mijn query op:
Dit functioneert in principe prima. Totdat ik vandaag testte met een huge datafile (2mb data), bestaande uit zo'n 13.000 regels. "MySQL has gone away" was de melding waar ik het mee moest doen. Even googlen leverde op dat dit betekent dat mijn query waarschijnlijk te groot is tov de standaard ingestelde 1Mb. Verschillende oplossingen kwamen in me op:
1. De max-query grootte aanpassen. Lekker simpel maar dat doe ik liever niet omdat dit een server-breedde aanpassing is, en omdat het script dan niet meer kan draaien op een server waar je geen invloed hebt op de MySQL configuratie.
2. Door het hele array heenloopen. Ook lekker simpel maar het betekent wel dat er 13.000 queries naar de server worden gestuurd ipv 1. Niet echt een fijne oplossing lijkt me zo...
3. Een wat intelligentere oplossing. Wat ingewikkelder, een slimme manier om de query op te splitsen in meerdere queries. Liefst van zo'n 1Mb groot. Een eerste aanzet tot deze mogelijkheid kwam uit op zoiets:
Deze laatste oplossingsrichting lijkt mij ook niet de meest efficiënte, maar tot nog toe wel de meest wenselijke. Hoe zouden jullie dit oplossen??
PHP:
1
| $query = 'INSERT INTO data ' .$Columns .' VALUES ' .implode(',', $DataInsertCases); |
Dit functioneert in principe prima. Totdat ik vandaag testte met een huge datafile (2mb data), bestaande uit zo'n 13.000 regels. "MySQL has gone away" was de melding waar ik het mee moest doen. Even googlen leverde op dat dit betekent dat mijn query waarschijnlijk te groot is tov de standaard ingestelde 1Mb. Verschillende oplossingen kwamen in me op:
1. De max-query grootte aanpassen. Lekker simpel maar dat doe ik liever niet omdat dit een server-breedde aanpassing is, en omdat het script dan niet meer kan draaien op een server waar je geen invloed hebt op de MySQL configuratie.
2. Door het hele array heenloopen. Ook lekker simpel maar het betekent wel dat er 13.000 queries naar de server worden gestuurd ipv 1. Niet echt een fijne oplossing lijkt me zo...
3. Een wat intelligentere oplossing. Wat ingewikkelder, een slimme manier om de query op te splitsen in meerdere queries. Liefst van zo'n 1Mb groot. Een eerste aanzet tot deze mogelijkheid kwam uit op zoiets:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| foreach ($DataInsertCases as $case) { if (!isset($tmpquery)) { $tmpquery = 'INSERT INTO pge_data ' .$DataColumnsInsert .' VALUES ' .$case; } else { $tmpquery .= ',' .$case; } if (strlen($tmpquery) > 900*1024) { $QUERY[] = $tmpquery; unset($tmpquery); } } |
Deze laatste oplossingsrichting lijkt mij ook niet de meest efficiënte, maar tot nog toe wel de meest wenselijke. Hoe zouden jullie dit oplossen??
Regeren is vooruitschuiven