Traitement fractionné d'une grande table de BDD
Bonjour,
Confronté au traitement séquentiel d'une table imposante de BDD, je tente de pratiquer une itération par blocs de 4000 lignes en utilisant les 2 paramètres complémentaires "LIMIT" & "OFFSET" à la fin de chaque requête.
Mon script présenté ci-dessous fonctionne parfaitement pour une table n'excédant pas 4000 lignes, mais au-delà le processus tourne indéfiniment sans aucun affichage de résultats.
Si je teste manuellement chaque boucle (ex: table de 14000 lignes) directement par phpmyadmin, tout est correct.
nb: si je place une instruction "break' entre mes 2 boucles "while" (cf. ligne 55) -pour cesser le processus à la fin de la 1ère boucle-, les résultats sont bons. Mon problème se situe donc bien dans le processus d'itération, dès le second passage (traitement des lignes 4001 à 8000), voire plus.
Code:
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
<?php
$conn = new mysqli('localhost','user','pass','bdd');
// décompte du nombre de lignes à traiter
$riq = "SELECT id FROM syw7g_ameliv
WHERE ((cp_ville != '') AND (a3 = 'C') AND (url IS NOT NULL) AND !(((code_profession = '60') AND (b5 = 'S'))
OR (code_profession = '86') OR (code_profession = '50') OR (code_profession = '21') OR (code_profession = '28') OR (code_profession = '98')))";
$resultat = $conn->query($riq) or die('Erreur SQL !'. $riq .'' . $conn->error);
$nbl = $resultat->num_rows;
// calcul du nombre d'itérations de 4000 lignes à traiter
$boucles = intval($nbl/4000);
$ntot = $boucles*4000;
if ($ntot < $nbl) {$boucles = $boucles + 1;}
// préparation du tableau d'affichage des résultats
echo '<table cellpadding="1" cellspacing="1" border="3" style="font-size:12px;">';
echo '<thead>';
echo '<tr class="centrer-noir">';
echo '<th class="centrer">Praticien</th>';
echo '<th class="centrer">Profession</th>';
echo '<th class="centrer">Spécialité</th>';
echo '<th class="centrer">Adresse</th>';
echo '<th class="centrer">Ville</th>';
echo '</tr>';
echo '</thead>';
echo '<tbody>';
$debut = -4000;
$ajout = 4000;
$num_boucle = 1;
while($num_boucle <= $boucles) {
$debut = $debut + 4000;
if ($num_boucle == $boucles) {$ajout = $nbl-$debut;}
$resultat->free();
$riq = "SELECT nom, prenom, profession, specialite, cp_ville, num_rue, voie, nom_voie, url FROM syw7g_ameliv
WHERE ((cp_ville != '') AND (a3 = 'C') AND (url IS NOT NULL) AND !(((code_profession = '60') AND (b5 = 'S')) OR (code_profession = '86') OR (code_profession = '50')
OR (code_profession = '21') OR (code_profession = '28') OR (code_profession = '98'))) ORDER BY nom LIMIT " .$ajout. " OFFSET " .$debut;
$resultat = $conn->query("SET NAMES utf8");
$resultat = $conn->query($riq) or die('Erreur SQL !'. $riq .'' . $conn->error);
while($arr = $resultat->fetch_array(MYSQLI_NUM)) {
echo '<tr>';
$nom = $arr[1] . ' ' .$arr[0];
$profession = ucfirst(mb_strtolower($arr[2]));
$specialite = ucfirst(mb_strtolower($arr[3]));
echo "<td class='centrer'>".$nom."</a></td>";
echo "<td class='centrer'>".$profession."</td>";
echo "<td class='centrer'>".$specialite."</td>";
echo "<td class='centrer'>".trim(mb_strtolower($arr[5])). " " .trim(mb_strtolower($arr[6])). " " .trim(mb_strtolower($arr[7]))."</td>";
echo "<td class='centrer'>".trim(mb_strtolower($arr[4]))."</td>";
echo '</tr>';
}
$num_boucle++;
}
echo '</tbody>';
echo '</table>';
$resultat->free();
$conn->close();
?> |
Peut-être ai-je mal dimensionné chaque bloc en prenant 4000 lignes ?
Merci à celui qui me trouvera mon erreur et me précisera le correctif à y apporter.
Bonne journée à tous.