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

SQL Procédural MySQL Discussion :

Optimisation ou problème d'index


Sujet :

SQL Procédural MySQL

  1. #21
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    qu130 : Merci pour ton conseil, je vais toutefois garder cette solution pour la fin

    Ré-essayons autre chose, si je décide de changer un des champs de ma clé primaire ssv_DateEntry pour un simple champs TimeStamp cela pourrait réduire la taille de la clé primaire ? Et ainsi accélérer le processus ? Si oui, alors dois-je procéder et quel est le type exacte de la colonne pour le nouveau champs ?

  2. #22
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 414
    Points : 672
    Points
    672
    Par défaut
    Je ne pense pas que tu gagneras énormément en changeant des types de colonnes.

    Tu n'es pas arrivé aux limites de Mysql (du moins j'espere ) et encore moins aux limites d'un SGBD je te rassure, on connait des tables beaucoup plus grosses avec des milliards de lignes.

    Par contre, avec 4m de lignes qui vont grossir, il est temps de songer au partitionnement de ta table.
    En plus, tu nous parles de moyenne au mois et la à la station, ta clé de partitionnement est quasiment trouvée !!!!
    Là tu gagneras énormément. Rien qu'en partitionannt à la station, tu passes de 4 millions de lignes à 20 partitions de 200000 ! Grosses améliorations en approche !!!

    2eme chose, tu fais des moyennes, peut etre pourrais tu utiliser des trucs de datawarehousing comme les vues matérialisées qui vont te permettre d'aggréger des données en fonction de ta table (remarque : aucune idée si cela existe en Mysql ). Et apres tu fais juste un select tout bete sur ta requete.

    Bon courage.

    Remarque, si Mysql ne répond pas à ca, peut etre songer à prendre un vrai SGBD un peu plus robuste

  3. #23
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Le partitionnement de tables n'est disponible que dans la version 5.1 qui est encore en bêta (release candidate prévue pour dans quelques mois tout au plus). Les vues matérialisées n'existent pas sous MySQL.

    Pour moi c'est le GROUP BY et pas forcément le AVG() qui ralentit la première requête car une table temporaire est créée. La n° 2 et la n° 3 doivent normalement être plus performantes.

  4. #24
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Lorsque l'utilisateur se rend dans l'interface Web permettant d'afficher la courbe graphique d'une station pour un mois précis, je dois parcourir la table à la recherche des dates MIN et MAX. Ainsi je peux par la suite proposer l'interval des dates disponibles à l'utilisateur. Mais, je me rend compte que juste faire cette opération c'est terriblement long.

    Je n'ai jamais travaillé avec les trigger mais la solution de qi130 semble intéressant pour me faire sauver du temps. Et par la suite j'attendrai la prochaine version de MySQL pour enfin partionner ma table.

    Citation Envoyé par qi130
    garder quelque part le nb de mesures et le cumul des valeurs (organisés par AAAA-MM/station/capteur), et mettre à jour ces valeurs lors de l'arrivée de nouvelles données via un trigger par exemple.
    Ainsi, tu aurais immédiatement dispo ce qui est utile pour calculer cette moyenne: cumul/nb_de_mesure
    => 1 seule ligne à lire

    Le gros du boulot étant fait au fil de l'eau de manière "indolore"

    (à la réflexion, c'est pas si lourd que ça, non ?)
    Idéalement lorsque le système reçoit des nouvelles données pour une station le trigger pourrait se déclancher et ainsi mettre à jour différent champs qui conservent par exemple (Min, Max, Moyenne, Écart-Type) pour chaque station (pour un jour, pour un mois et pour l'année et pour toute les données)

    Cependant quelqu'un aurait un exemple ou un petit coup de main à me donner pour créer mon trigger ?

    Merci

  5. #25
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 926
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 926
    Points : 6 040
    Points
    6 040
    Par défaut
    Un coup d'oeil ici pour commencer...
    http://dev.mysql.com/doc/refman/5.0/fr/triggers.html

  6. #26
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 926
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 926
    Points : 6 040
    Points
    6 040
    Par défaut
    mais c'est extrèmement rudimentaire

    Peux-tu décrire la manière avec laquelle les données arrivent et sont insérées en base ?

  7. #27
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Les données arrive sous forme de fichiers. Une fichier par station au 4h.
    J'ouvre un fichier et je lis ligne par ligne afin de construire la requête d'insertion qui donne ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    INSERT IGNORE StationsSensorsValues (ssv_DateEntry, ssv_StationID, ssv_SensorID, ssv_Value) 
    VALUES (x, x, x, x), (x, x, x, x), (x, x, x, x), (x, x, x, x), .... 
    ON DUPLICATE KEY UPDATE ssv_Value = VALUES(ssv_Value);
    
    Ensuite j'exécute cette requête sur le serveur MySQL.

  8. #28
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 926
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 926
    Points : 6 040
    Points
    6 040
    Par défaut
    Alors, puisque tu as la main sur les données, tu n'as même pas besoin du trigger

    Il "suffit" de comptabiliser les mesures (nb et cumul des valeurs) puis d'enrichir le "passif" des mesures.

  9. #29
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Citation Envoyé par qi130
    Alors, puisque tu as la main sur les données, tu n'as même pas besoin du trigger

    Il "suffit" de comptabiliser les mesures (nb et cumul des valeurs) puis d'enrichir le "passif" des mesures.
    Et bien je vais tenter cette approche et attendre impatiemment le système de partitions de la nouvelle version de MySQL.

    Mais juste comme ça qu'est-ce que cela aurait eu l'air avec les triggers ? En code SQL je veux dire...

    Merci beaucoup.

  10. #30
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 926
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 926
    Points : 6 040
    Points
    6 040
    Par défaut
    De plus, compte-tenu du mode d'alimentation des tables (assimilable à un LOAD), le trigger ne pouvait pas être mis en oeuvre.

    Par contre on aurait pu l'utiliser dans un contexte où les mesures arrivent au compte-goutte (genre 1/mn).

    Là où MySQL me déçoit un peu, c'est qu'un trigger ne peut pas (encore ?) appeler une PS .
    J'espère que ça viendra rapidement.

  11. #31
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Re-bonjour à tous.

    Ce matin j'ai ouvert MySQLAdministrator et j'ai regardé l'état de ma table :

    Est-ce que c'est normal un index length de 228.5 MB pour la ta taille de la table qui fait 217.8 MB ?

    Mon index est plus gros que ma table ???

    Merci à tous.

  12. #32
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 681
    Points
    18 681
    Par défaut
    pas du tout impossible... tout dépend de ce que tu as mis dans ton index.

  13. #33
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Bonjour,

    En rappel de ce que j'ai maintenant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    CREATE TABLE `stationssensorsvalues` (
      `ssv_DateEntry` datetime NOT NULL default '0000-00-00 00:00:00',
      `ssv_StationID` int(11) NOT NULL default '0',
      `ssv_SensorID` int(11) NOT NULL default '0',
      `ssv_Value` float NOT NULL default '0',
      PRIMARY KEY  (`ssv_DateEntry`,`ssv_StationID`,`ssv_SensorID`),
      KEY `ssv_StationID` (`ssv_StationID`),
      KEY `ssv_SensorID` (`ssv_SensorID`),
      CONSTRAINT `stationssensorsvalues_ibfk_1` FOREIGN KEY (`ssv_StationID`) REFERENCES `stations` (`s_ID`),
      CONSTRAINT `stationssensorsvalues_ibfk_2` FOREIGN KEY (`ssv_SensorID`) REFERENCES `sensors` (`s_ID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

  14. #34
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Re-bonjour à tous.

    J'ai fais des test une bonne partie de la journée d'hier et j'ai finalement trouvé un bon compromis.

    Voilà ma nouvelle table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE TABLE `stationssensorsvalues` (
      `ssv_StationID` int(11) NOT NULL default '0',
      `ssv_Year` smallint(4) NOT NULL default '0',
      `ssv_Month` tinyint(2) NOT NULL default '0',
      `ssv_Day` tinyint(2) NOT NULL default '0',
      `ssv_Time` time NOT NULL default '00:00:00',
      `ssv_SensorID` int(11) NOT NULL default '0',
      `ssv_Value` float NOT NULL default '0',
      PRIMARY KEY  (`ssv_StationID`,`ssv_Year`,`ssv_Month`,`ssv_Day`,`ssv_Time`,`ssv_SensorID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    De cette manière j'ai obtenu 100% et + d'amélioration en rapport avec les recherches des années MIN et MAX pour une station précise. Ou encore pour les mois MIN et MAX d'une station précise et d'une année précise. J'ai testé aussi les autres requêtes servant à créer les graphiques et elles aussi ont été très bénéfique en temps de réponse comparé à l'ancien format de ma table.

    Donc le problème se situait entre autre dans la lenteur extrême avec les DateTime et l'ordre de la clé (Date_Entry <-> StationID)

    Cependant j'ai un nouveau problème de requête. Supposons que je veuille récupérer toutes les valeurs pour la station 4 et ce entre deux dates précise ? Disons entre le 2006-06-07 15:00:00 et 2006-06-09 2:30:00.

    Je ne peux pas faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT ... 
    FROM StationsSensorsValues 
    WHERE ssv_StationID = 4 AND
              ssv_Year BETWEEN minDateYear AND maxDateYear AND
              ssv_Month BETWEEN minDateMonth AND maxDateMonth AND
              ssv_Day BETWEEN minDateDay AND maxDateDay AND
              ssv_Time BETWEEN minDateTime AND maxDateTime;
    Puisqu'il ne doit pas prendre en considération le temps pour le jour 8.
    Quelqu'un à une solution ?
    Merci à tous.

  15. #35
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 926
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 926
    Points : 6 040
    Points
    6 040
    Par défaut
    Puisqu'il ne doit pas prendre en considération le temps pour le jour 8.
    Je ne comprends pas pourquoi le 08-06-2006 est à ignorer

  16. #36
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Citation Envoyé par qi130
    Je ne comprends pas pourquoi le 08-06-2006 est à ignorer
    Ce que je veux dire c'est que la partie TIME de la date est à ignorer le jour 8. On doit seulement prendre la partie TIME du temps en considération que le premier jour et le dernier.

    Cela pourrait être différent dans le cas d'un autre requête, par exemple je pourrais demandé les valeurs entre les dates suivantes : 2006-05-01 00:00:00 et 2006-06-01 2:30:00. Donc à ce moment-ci, la partie TIME serait importante seulement pour cette journée 2006-06-06 et celle-ci 2006-05-02. Et la partie JOUR serait importante seulement le premier et le dernier mois.

Discussions similaires

  1. Problèmes d'index ?
    Par dd16 dans le forum Oracle
    Réponses: 1
    Dernier message: 07/06/2006, 09h59
  2. [mysql] Toujours ce problème d'index !!
    Par LE NEINDRE dans le forum Requêtes
    Réponses: 8
    Dernier message: 12/10/2005, 18h05
  3. [perl]Problème tableau indexé
    Par LE NEINDRE dans le forum Langage
    Réponses: 8
    Dernier message: 25/08/2005, 22h24
  4. Problème d'index avec load data file
    Par bruno782 dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 09/03/2005, 13h11
  5. Problème d'index
    Par claude dans le forum SQL
    Réponses: 6
    Dernier message: 04/08/2003, 16h55

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