IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Selection de plusieurs millions de lignes [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Membre régulier Avatar de stomerfull
    Inscrit en
    Septembre 2005
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 307
    Points : 122
    Points
    122
    Par défaut Selection de plusieurs millions de lignes
    Bonjour,

    Je travaille sur un script permettant de selection des données d'un table et la mise à jour d'une autre table avec les données précedement selectionnés

    voici la requête pour que vous puisse comprendre facilement ce que je veux faire

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    update contact c 
    set c.flag_mail = 1, c.date_mail = 
      select distinct date_envoi 
      FROM flag_envoi_mail 
      where flag_envoi_mail.id_contact = c.id_contact

    Je voudrais mettre à jour la table contact avec les données de la table flag_envoi_mail

    le soucis c'est que la table flag_envoi_mail contient plus de 8 millions de ligne

    J'obtient l'erreur suivant :



    J’implémente ce requete dans un script php qui interroge la table mysq et
    j'ai ajouté ça dans le fichier setting.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ini_set('memory_limit', '250M');
    mais sans résultat

    voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    function synchro()
    {
    	$tab = array();
    	$query = "SELECT DISTINCT id_contact,date_envoi FROM flag_envoi_mail  ";
        //print $query; exit;
    	$result = db_query($query);
        while ($data = db_fetch_object($result)) {
            $tab[$data-> id_contact] = $data->date_envoi;
        }
    	return $tab;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    function principale_synchro()
    {
     
    	foreach(synchro() as $key=>$val)
    	{
    		$query = "update contact set flag_mail = 1 , date_mail = '".$val."' 
    		WHERE id_contact = '".$key."' ";
    		print $query . "<br />";
    		//db_query($query);
    	}
     
    }
    jobtient l'erreur suivant :

    PHP Fatal Error: Allowed memory size of 8388608 bytes exhausted ....


    Comment puis-je executer ce script , utilisation d'ajax ou autre ?

    merci d'avance pour votre aide

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UPDATE contact c 
    SET c.flag_mail = 1, c.date_mail = 
      SELECT DISTINCT date_envoi 
      FROM flag_envoi_mail 
      WHERE flag_envoi_mail.id_contact = c.id_contact
    Avec ta requête, si un contact est référencé 1000 fois dans la table flag_envoi_mail, il y aura 1000 mises à jour de ce contact !

    Je pense que ce que tu veux faire, c'est de mettre la date du mel le plus récent du contact dans la table contact ?
    Cette requête permet de trouver la date du dernier mel de chaque contact :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id_contact, MAX(date_envoi) AS derniere_date
    FROM flag_envoi_mail
    GROUP BY id_contact

    Fais une jointure dessus dans ta requête UPDATE et le tour est joué :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    UPDATE contact c 
    INNER JOIN
    (
    	SELECT id_contact, MAX(date_envoi) AS derniere_date
    	FROM flag_envoi_mail
    	GROUP BY id_contact
    ) tmp ON tmp.id_contact = c.id_contact
    SET c.flag_mail = 1,
    	c.date_mail = tmp.derniere_date

    Si tu as encore des problèmes de lenteur, regarde si tes tables sont correctement indexées. Vérifie notamment si tu as un index sur flag_envoi_mail.id_contact puisque c'est une clé étrangère et sur flag_envoi_mail.date_envoi.

    Un index sur ces deux colonnes pourrait aussi être utile.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Membre régulier Avatar de stomerfull
    Inscrit en
    Septembre 2005
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 307
    Points : 122
    Points
    122
    Par défaut
    Merci pour votre réponse

    Dans la table flag_envoi_mail il n' y a qu'un seul enregistrement d'un contact c'est à dire pas de doublons d 'id_contact donc pas de soucis d e ce coté

    et je ne cherche pas à mettre la date du mel le plus récent du contact dans la table contact

    ce que je veux faire c'est de mettre à jour le champ flag_mail et date_mail de la table contact avec les données dans flag_envoi_mail avec id_contact la clé étrangère de la table contact

    Je ne sais pas si je me suis bien exprimé

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par stomerfull Voir le message
    Dans la table flag_envoi_mail il n' y a qu'un seul enregistrement d'un contact c'est à dire pas de doublons d 'id_contact donc pas de soucis d e ce coté
    Tu veux dire que tu as 8 millions de contacts ?

    ce que je veux faire c'est de mettre à jour le champ flag_mail et date_mail de la table contact avec les données dans flag_envoi_mail avec id_contact la clé étrangère de la table contact
    Alors puisque ces données existent déjà dans la table flag_envoi_mail, inutile de les copier dans la table contact !

    Quel est le but de cette opération ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Membre régulier Avatar de stomerfull
    Inscrit en
    Septembre 2005
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 307
    Points : 122
    Points
    122
    Par défaut
    Bonjour,

    Merci pour la réponse :

    Je te decrit le scenario :

    La table contact stocke les contacts c'est a dire les personnes physiques

    Un script gère l'envoi de mail cron tous les soirs à ses contacts et enregistres dans la table flag_envoi_mail les contacts

    qui ont reçu le mail

    C'est à dire on n'envoi plus de mail au contact stocker dans la table flag_envoi_mail


    les champs dans la table flag_envoi_mail sont : id_contact et date_envoi : la clé étrangère de contact et la date de l'envoi de mail


    Le souci c'est que cette table (flag_envoi_mail) devient de jour en jour lourds (+ de 8 millions de ligne) le script(CRON) met plusieurs heures à s'executer

    dONC j'ai decider de créer directement les duex champs directement dans la table contact (flag_mail (qui prend deux valeur 1 si l'utilisateur a reçu le mail , 0 pour les utilisateurs n'ayant pas encore reçu le mail) et date_envoi)

    C'est pourquoi j'ai besoin de synchroniser ces deux tables c'est à dire copier les données dans flag_envoi_mail dans contact


    Je ne sais pas si je me suis bien exprimé

  6. #6
    Membre régulier Avatar de stomerfull
    Inscrit en
    Septembre 2005
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 307
    Points : 122
    Points
    122
    Par défaut
    j'ai résolu en utilisation ajax avec prototype

    Merci quand même pour les réponses

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Awk - Création d'un jeu de données csv de plusieurs millions de lignes
    Par MvK0610 dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 16/06/2015, 16h01
  2. selection de plusieurs lignes
    Par otaquet dans le forum SQL
    Réponses: 6
    Dernier message: 18/10/2007, 14h49
  3. VB Excel : copier coller selection de plusieurs lignes
    Par skuzo_mars dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 14/01/2007, 14h48
  4. Réponses: 10
    Dernier message: 16/09/2006, 11h41
  5. [SELECT sur 16 millions de lignes] délai très grand
    Par localhost dans le forum Requêtes
    Réponses: 6
    Dernier message: 22/11/2004, 17h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo