Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment récupérer de grands ensembles de données sur plusieurs tables et éviter les requêtes en boucle

En supposant que vos 7 tables sont liées par des identifiants, faites quelque chose comme ça

Première requête

'SELECT * FROM table_a WHERE a_id IN (12,233,4545,67676,898999)'
// store the result in $result_of_first_query

Ensuite, faites un foreach et choisissez les identifiants que vous souhaitez utiliser dans la requête suivante dans une variable séparée par des virgules (csv)

foreach($result_of_first_query as $a_row_from_first_table)
{
    $csv_for_second_query = $csv_for_second_query.$a_row_from_first_table['b_id'].",";
}

$csv_for_second_query = trim($csv_for_second_query,", "); // problem is we will have a lot of duplicate entries
$temp_arr = array(); // so lets remove the duplicates
$temp_arr = explode(",",$csv_for_second_query);  // explode values in array
$temp_arr = array_unique($temp_arr);  // remove duplicates
$csv_for_second_query = implode(",",$temp_arr);  // create csv string again. ready!

maintenant pour votre deuxième table, vous obtiendrez, avec seulement 1 requête toutes les valeurs dont vous avez besoin pour JOIN (pas par mysql, nous le ferons avec php)

Deuxième requête

'SELECT * FROM table_b where a_id IN ('.$csv_for_second_query.')'
// store the result in $result_of_second_query;

Ensuite, nous avons juste besoin de joindre par programmation les deux tableaux.

$result_a_and_b = array(); // we will store the joined result of every row here

// lets scan every row from first table
foreach($result_of_first_query as $inc=> $a_row_from_first_table)
{
    // assign every row from frist table to result_a_and_b 
    $result_a_and_b[$inc]['a']=$a_row_from_first_table;

    $inc_b=0; // counter for the joins that will happen by data from second table

    // for every row from first table we will scan every row from second table
    // so we need this nested foreach
    foreach($result_of_second_query as $a_row_from_second_table)
    {
        // are data need to join? if yes then do so! :)
        if($a_row_from_first_table['a_id']==$a_row_from_second_table['a_id'])
        {
            $result_a_and_b[$inc]['b'][$inc_b]=$a_row_from_second_table; // "join" in our "own" way :)
            ++$inc_b; // needed for the next join
        }
    }
}

nous avons maintenant le tableau $result_a_and_b avec ce format :

$result_a_and_b[INDEX]['a']
$result_a_and_b[INDEX]['b'][INDEX]

donc avec 2 requêtes, nous avons un résultat similaire à TABLE_A_ROWS_NUMBER + 1 (l'un est la requête initiale de la première table)

Comme ça, continuez à faire autant de niveaux que vous voulez.

  1. Interroger la base de données avec l'identifiant qui relie la table
  2. obtenir les identifiants dans la chaîne CSV
  3. faites une requête dans le champ suivant en utilisant WHERE id IN(11,22,33,44,55,.....)
  4. rejoindre par programmation

Astuce :Vous pouvez utiliser unset() pour libérer de la mémoire sur les variables temporaires.

Je crois avoir répondu à votre question "Existe-t-il un moyen de ne pas interroger la base de données si souvent ?"

note :le code n'a pas été testé pour les fautes de frappe, j'ai peut-être manqué une virgule ou deux - ou peut-être pas

je crois que vous pouvez comprendre :) j'espère que cela vous aidera !