1. #21
    Membre à l'essai
    Inscrit en
    mai 2009
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : mai 2009
    Messages : 42
    Points : 21
    Points
    21

    Par défaut

    En fait, j'importe simplement la sauvegarde de base d'origne contenant les donnees de la veille.

    Merci ta precision je vais utiliser a.TypEvent=A and b.TypEvent=B au lieu "<>".

    Oui je conserve les memes colonnes mais apres je rajoute les indexes qui vont bien pour optimiser ma requetes.

    Merci.

  2. #22
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    décembre 2013
    Messages
    1 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : décembre 2013
    Messages : 1 455
    Points : 3 039
    Points
    3 039

    Par défaut

    Pour optimiser ta requête, ça ne sert à rien d'ajouter plusieurs indexes. Une requête ne peut utiliser qu'un index par table. Ici, ta requête lit 2 fois la table_analyse... donc au mieux, elle utilisera 2 indexes.
    Ici, un index sur la clé composée Type_Event+ChanalNumber+Start_Event+End_Event devrait déjà donner de bons résultats. Index quasi indispensable.

    Eventuellement, l'index ci-dessus, plus un autre index sur Start_Event seul ou Start_Event+Type_Event.

    Et une partition par mois, un peu pour la performance de la requête, mais surtout pour la maintenance.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  3. #23
    Expert éminent Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    février 2011
    Messages
    2 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : février 2011
    Messages : 2 903
    Points : 8 557
    Points
    8 557

    Par défaut

    Salut Hilal74.

    Voici mes questions :

    1) dans votre premier message, vous nous indiquez brièvement la structure de vos lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    unique_id; 01/01/2016 12:00:20; typ1; typ2;
    ...
    unique_id; 01/01/2017 12:30:03; typ1; typ2;
    ...
    unique_id; 13/02/2017 04:00:16;
    ...
    unique_id; 27/07/2017 23:00:00;
    Puis dans le message #16, vous nous indiquez une autre structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    1; Start_Event; Stop_Event; ChanalNumber; TypEvent; ModuleEvent
    2; Start_Event; Stop_Event; ChanalNumber; TypEvent; ModuleEvent
    Pouvez-vous nous expliqué ce changement ?

    2) Ensuite, vous nous communiquez une requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Select      *
     
          from  maTable  as a 
    inner join  maTable  as b 
                     on  b.ChanalNumber =  a.ChanalNumber
                    and  b.TypEvent     <> a.TypEvent
     
         where  a.Start_Event < b.Stop_Event
           and  a.Stop_ Event > b.Start_Event
           and  a.Start_Event between '2015-01-01 00:00:00' and '2015-02-28 00:00:00'
           and  a.Start_Event between '2015-01-01 00:00:00' and '2015-02-28 00:00:00';
    Je l'ai mise en forme et j'ai corrigé la présentation.

    je suis parti sur l'excellente idée de Escartefigue, partitionner votre table par mois et ce, sur deux ans.
    Nous sommes donc parti sur le premier modèle de vos données, à savoir une date au type timestamp.
    Or maintenant, nous nous retrouvons avec deux dates, l'une étant le début de la période et l'autre la fin de la période.

    Ce qui pose problème, c'est la construction du partitionnement qui doit impérativement se faire sur une date et non deux.
    Ensuite, mais je pense que vous ne devez pas savoir, pour des raisons de performances, une requête devra être associé à un partitionnement.
    Sinon partitionner n'a aucun intérêt si vous devez balayer la totalité de votre table.

    3) il y a plusieurs erreurs dans votre requête.
    Dans le select, vous ne précisez pas les colonnes à extraire. Pourquoi ?

    4) Dans la jointure, vous précisez "b.TypEvent <> a.TypEvent". Or ce n'est pas une jointure !
    vous précisez ceci :
    Citation Envoyé par Hilal74
    un événement est toujours caractérisé par deux lignes TypEvent=A et TypEvent=B qui contiennent des informations complémentaires:
    Autrement dit, on doit associer un type = A avec un type = B sachant que nous ne savons pas lequel est en premier.
    Autant créer une jointure, basé sur le fait que si nous avons "A", nous devons mettre "B" et vice-verça.
    Ce qui donne : "and b.TypEvent = case when a.TypEvent = 'a' then 'b' else 'a' end".
    Est-ce ce genre de résultat que vous voulez faire ?

    5) vous nous dites :
    Citation Envoyé par Hilal74
    chaque fois qu'il y a un événement il y a deux tickets insérés dans la base. (sa structure d'origine est celle du constructeur).
    Dois-je comprendre que les lignes de type "A" et de type "B" sont ce que vous appelez des tickets ?
    Et cela correspond à la structure de vos lignes dans votre premier message. Est-ce bien cela ?

    6) vous ne précisez pas la relation qui existe entre le type "A" (ticket A) et le type "B" (ticket B) ?
    Comment mettez-vous ces deux lignes en relation ?
    Dois-je comprendre que cela se fait par votre requête ?

    7) Vous répétez deux fois la condition "and a.Start_Event between '2015-01-01 00:00:00' and '2015-02-28 00:00:00'".
    Dois-je comprendre que l'une se fait sur l'alias "a" et l'autre sur l'alias "b".

    8) Dois-je comprendre que vous pouvez avoir des "start" et des "end" à cheval sur deux mois ?
    Dans ce cas là, le partionnement de votre table ne sert à rien.

    9) Ce n'est pas une erreur, mais je vais quand même détailler la condition sur les deux périodes.
    Normalement vous testez ceci : "a.start < b.start < a.stop < b.stop", c'est à dire le chevauchement des deux périodes.
    Or vous testez : "a.start < b.stop and b.start < a.stop".

    Vu que l'on ne sait pas si un test élémentaire à été fait sur : "a.start <= a.stop" et "b.start <= v.stop", je ne suis pas certain qu'il fonctionne dans tous les cas.
    Par sécurité, il faudrait mieux faire ce genre de test :
    --> a.start <= b.start <= a.end
    --> b.start <= a.end <= b.end
    Vous remarquez l'encadrement de "b.start" par rapport à "a.start" et "a.end".
    Et de même, l'encadrement de "a.end" par rapport à "b.start" et "b.end".

    Je ne dis pas que votre test est faux, mais il sous-entend que les tests élémentaires, à savoir
    --> a.start <= a.end
    --> b.start <= b.end
    ont été fait au préalable. Mais rien ne le prouve !

    10) Dans ce genre de recherche, vous risquez d'avoir des doublons lors de l'extraction des lignes, du genre :
    --> a.start, a.end et b.start, b.end
    --> b.start, b.end et a.start, a.end
    C'est pourquoi le test que vous avez mis "a.start < b.end" permet d'éviter les doublons.

    11) En ce qui concerne les chevauchements, pouvons-nous avoir plusieurs lignes (> 2) qui peuvent répondre à ce cas ?
    Comment devons-nous traiter le cas où cela se présente ? Ou bien c'est un cas qui ne se présente pas ?

    12) Pouvez-vous nous communiquer une jeu d'essai représentatif de ce que vous avez comme lignes tickets ?
    Et un exemple de résultat à produire ?

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  4. #24
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    décembre 2013
    Messages
    1 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : décembre 2013
    Messages : 1 455
    Points : 3 039
    Points
    3 039

    Par défaut

    Sur la partie 'chevauchement de période', imaginons cette configuration :
    A : de 10h05 à 10h09
    B : de 10h06 à 10h07

    ou bien
    A : de 10h06 à 10h07
    B : de 10h05 à 10h09

    Ils ne seront pas récupérés avec le test A.Start <= B.Start <= A.End <= B.End alors qu'ils sont récupérés avec le test A.Start < B.End and B.Start < A.End.
    Je pense que Hilal74 veut récupérer ces couples mais rien ne le dit.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  5. #25
    Membre à l'essai
    Inscrit en
    mai 2009
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : mai 2009
    Messages : 42
    Points : 21
    Points
    21

    Par défaut

    Salut Artemus24,

    1) dans votre premier message, vous nous indiquez brièvement la structure de vos lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    unique_id; 01/01/2016 12:00:20; typ1; typ2;
    ...
    unique_id; 01/01/2017 12:30:03; typ1; typ2;
    ...
    unique_id; 13/02/2017 04:00:16;
    ...
    unique_id; 27/07/2017 23:00:00;
    Puis dans le message #16, vous nous indiquez une autre structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    1; Start_Event; Stop_Event; ChanalNumber; TypEvent; ModuleEvent
    2; Start_Event; Stop_Event; ChanalNumber; TypEvent; ModuleEvent
    Pouvez-vous nous expliqué ce changement?
    La derniere structure est la bonne, j'ai bien un starttime et un stoptime. Desole, j'ai neglige cette information car je ne pensais pas qu'elle allait avoir une importance dans le partionnement.


    2) Ensuite, vous nous communiquez une requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Select      *
     
          from  maTable  as a 
    inner join  maTable  as b 
                     on  b.ChanalNumber =  a.ChanalNumber
                    and  b.TypEvent     <> a.TypEvent
     
         where  a.Start_Event < b.Stop_Event
           and  a.Stop_ Event > b.Start_Event
           and  a.Start_Event between '2015-01-01 00:00:00' and '2015-02-28 00:00:00'
           and  a.Start_Event between '2015-01-01 00:00:00' and '2015-02-28 00:00:00';
    Je l'ai mise en forme et j'ai corrigé la présentation.

    je suis parti sur l'excellente idée de Escartefigue, partitionner votre table par mois et ce, sur deux ans.
    Nous sommes donc parti sur le premier modèle de vos données, à savoir une date au type timestamp.
    Or maintenant, nous nous retrouvons avec deux dates, l'une étant le début de la période et l'autre la fin de la période.

    Ce qui pose problème, c'est la construction du partitionnement qui doit impérativement se faire sur une date et non deux.
    Ensuite, mais je pense que vous ne devez pas savoir, pour des raisons de performances, une requête devra être associé à un partitionnement.
    Sinon partitionner n'a aucun intérêt si vous devez balayer la totalité de votre table.
    Je pense que le fait d'utliser la colonne starttime pour le partitionnement fera l'affaire, ainsi mes tickets seront divises par mois. Il faut voir ces evenements comme des appels telephoniques et un appel aura deux tickets de type different, ces tickets (A et B) apportent des informations complementaires a l'appel. Par ex avec le ticket A on aura le nom de l'appellant et le ticket B on aura la duree de l'appel. On a deux tickets car ces informatios viennent de deux sources differentes et ces tickets sont lies par le canal a.canal=b.canal et a.startEvent < b.StopEvent and a.StopEvent > b.StartEvent (car c'est le meme appel).


    3) il y a plusieurs erreurs dans votre requête.
    Dans le select, vous ne précisez pas les colonnes à extraire. Pourquoi ?
    La encore c'est une negligeance de ma part, la requete comporte bien des colonnes.

    4) Dans la jointure, vous précisez "b.TypEvent <> a.TypEvent". Or ce n'est pas une jointure !
    vous précisez ceci :

    Autrement dit, on doit associer un type = A avec un type = B sachant que nous ne savons pas lequel est en premier.
    Autant créer une jointure, basé sur le fait que si nous avons "A", nous devons mettre "B" et vice-verça.
    Ce qui donne : "and b.TypEvent = case when a.TypEvent = 'a' then 'b' else 'a' end".
    Est-ce ce genre de résultat que vous voulez faire ?
    Je placerai plus tout cela dans ma clause where

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    where 
    a.TypEvent=A
    and b.TypEvent=B....
    5) vous nous dites :

    Dois-je comprendre que les lignes de type "A" et de type "B" sont ce que vous appelez des tickets ?
    Et cela correspond à la structure de vos lignes dans votre premier message. Est-ce bien cela ?
    Oui, j'ai deux tickets un de type A et un autre de type B qui contiennent des informations complementaires sur l'appel.

    6) vous ne précisez pas la relation qui existe entre le type "A" (ticket A) et le type "B" (ticket B) ?
    Comment mettez-vous ces deux lignes en relation ?
    Dois-je comprendre que cela se fait par votre requête ?
    Les tickets A et B appartiennent au meme appel et sont lies par le canal et date debut et fin d'appel (StartEvent/StopEvent) il peut y avoir un decalge de quelques secondes entres les deux tickets car ces proviennent de deux sources differentes d'ou
    a.StartEvent < b.StopEvent and a.StopEvent > b.Startevent.


    7) Vous répétez deux fois la condition "and a.Start_Event between '2015-01-01 00:00:00' and '2015-02-28 00:00:00'".
    Dois-je comprendre que l'une se fait sur l'alias "a" et l'autre sur l'alias "b".
    En fait, c'est pour lancer ma requete sur un mois particulier. Oui ce sont des alias faisant references aux ticket A et ticket B.

    8) Dois-je comprendre que vous pouvez avoir des "start" et des "end" à cheval sur deux mois ?
    Dans ce cas là, le partionnement de votre table ne sert à rien.
    Non, la duree d'un appel est de 5 min en moyenne. En faisant un filtre sur le StartEvent (ou StartTime) comme cela StartEvent between '2017-08-02 00:00:00' and '2017-08-03 00:00:00' j'ai bien tous appels de la journee.

    9) Ce n'est pas une erreur, mais je vais quand même détailler la condition sur les deux périodes.
    Normalement vous testez ceci : "a.start < b.start < a.stop < b.stop", c'est à dire le chevauchement des deux périodes.
    Or vous testez : "a.start < b.stop and b.start < a.stop".

    Vu que l'on ne sait pas si un test élémentaire à été fait sur : "a.start <= a.stop" et "b.start <= v.stop", je ne suis pas certain qu'il fonctionne dans tous les cas.
    Par sécurité, il faudrait mieux faire ce genre de test :
    --> a.start <= b.start <= a.end
    --> b.start <= a.end <= b.end
    Vous remarquez l'encadrement de "b.start" par rapport à "a.start" et "a.end".
    Et de même, l'encadrement de "a.end" par rapport à "b.start" et "b.end".

    Je ne dis pas que votre test est faux, mais il sous-entend que les tests élémentaires, à savoir
    --> a.start <= a.end
    --> b.start <= b.end
    ont été fait au préalable. Mais rien ne le prouve !
    Je partirai plutot sur une clause where comme mentionne ci dessus. Qu'en pensez vous?

    10) Dans ce genre de recherche, vous risquez d'avoir des doublons lors de l'extraction des lignes, du genre :
    --> a.start, a.end et b.start, b.end
    --> b.start, b.end et a.start, a.end
    C'est pourquoi le test que vous avez mis "a.start < b.end" permet d'éviter les doublons.

    11) En ce qui concerne les chevauchements, pouvons-nous avoir plusieurs lignes (> 2) qui peuvent répondre à ce cas ?
    Comment devons-nous traiter le cas où cela se présente ? Ou bien c'est un cas qui ne se présente pas ?
    J'aurai toujours deux lignes par appel (un de type A et un autre de type B).

    12) Pouvez-vous nous communiquer une jeu d'essai représentatif de ce que vous avez comme lignes tickets ?
    Et un exemple de résultat à produire ?
    Example d'un appel ( la table en contient enormement):

    uniqueID;StartEvent;StopEvent;AgentName;CallingNum;.....
    34;2017-07-23 12:32:03;2017-07-23 12:37:03;Martin;;..............;typeA
    35;2017-07-23 12:32::09;2017-07-23 12:37:11;;01555668900;................;typeB

    En fait j'ai essaye d'ajouter un index compose de plusieurs colonnes mais cela n'a fait qu'augmenter le temps d'execution. Dans cette index j'ai mis (StartEvent, StopEvent, ChannelEvent, TypEvent), comment puis identigier la colonne qui a ralenti ma requete?


    Merci Artemus24

    A+

  6. #26
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    décembre 2013
    Messages
    1 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : décembre 2013
    Messages : 1 455
    Points : 3 039
    Points
    3 039

    Par défaut

    Quand tu crées un index sur Start+End+Type+Chanal, ça ne sert quasiment à rien, c'est comme si tu mettais un index sur start.

    Pourquoi ça ne sert à rien ?
    Le moteur lit une ligne ( table a). Il cherche dans table b une ou des lignes qui correspondent. S'il veut utiliser l'index, ca lui dit : prend toutes les lignes telles que b.start < a.end ... et donc en gros, ça lui donne la moitié de la table ( ou même beaucoup plus, mais passons). Pour chaque ligne lue dans la table a, il doit donc lire la moitié de l'index pour chercher la ou les lignes correspondantes.

    Si par contre tu crées un index sur type+chanal+Start+end, Ca l'aide énormément. L'ordre des colonnes dans l'index est essentiel. Start+end+type+Chanal, ce n'est pas du tout la même chose que type+Chanal+Start+end

    Pour chaque ligne lue de la table a, il sait immédiatement où aller chercher la ou les lignes de la table b : il sait qu'il faut aller chercher dans la section type='B' et dans la sous section Chanal = le même chanal que A. Au lieu de chercher dans la moitié de la table (b.start < a.end), il cherche dans 0.0025% de la table environ : 2000 fois plus rapide.

    Je triche un peu... mais soyons pessimiste, disons 100 fois plus rapide avec l'index proposé.
    Mais dans la requête , il faut absolument dire a.type ='A' and b.type='B' ; si tu dis simplement a.type < b.type, alors il ne saura pas utiliser l'index ; l'index lui servira juste à chercher dans la moitié de la table ... comparable à ce que tu as actuellement.

    Un index est extrêmement utile pour des recherches de type = , il permet d'aller directement à l'enregistrement voulu , ou au groupe d'enregistrements voulus. Pour des recherche de type <, il va aider un peu, il va permettre de lire la moitié de la base, au lieu de tout lire, mais c'est marginal.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  7. #27
    Membre à l'essai
    Inscrit en
    mai 2009
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : mai 2009
    Messages : 42
    Points : 21
    Points
    21

    Par défaut

    Salut tbc92,

    merci pour ces precisions.

    Mais ce que je ne comprends pas c'est qu'apres avoir ajoute un index cela n'a fait que ralentir ma requete, j'ai meme essaye avec un seul index sur la colonne Channel puis type mais meme resultat aucune amelioration au contraire un ralentissement.

    Est ce le fait que j'utilise une jointure sur la meme table? car je vois une amelioration quand je fais une simple requete avec une clause where sur la colonne Channel et avec un index sur Channel mais pas quand j'utilise ma jointure.

    Merci

  8. #28
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    décembre 2013
    Messages
    1 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : décembre 2013
    Messages : 1 455
    Points : 3 039
    Points
    3 039

    Par défaut

    Je connais SQL en général, mais pas suffisamment MySQL.

    Dans d'autres environnements, je dirais ces 2 mots clés : Mise à jour des statistiques. Et plan d'exécution. A toi de voir ce que ces mots-clés donnent sous My-Sql.

    Ici, l'index aide (théoriquement) à trouver les lignes de b qui correspondent à une ligne de a. Il faut peut-être un autre index (ou préciser une partition) pour aider à trouver les lignes de a qui nous intéressent.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  9. #29
    Expert éminent Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    février 2011
    Messages
    2 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : février 2011
    Messages : 2 903
    Points : 8 557
    Points
    8 557

    Par défaut

    Salut à tous.

    Citation Envoyé par tbc92
    Ils ne seront pas récupérés avec le test A.Start <= B.Start <= A.End <= B.End
    Ce n'est pas ce que j'ai écrit. Le test à faire se décompose en deux conditions :
    (1) --> a.start <= b.start <= a.end
    (2) --> b.start <= a.end <= b.end
    dont la condition est (1) OU (2) !

    Si je reprends vos deux exemple, cela donne :

    Pour le premier exemple, c'est le test (1) qui fonctionne :
    (1) --> (a.start) 10h05 <= (b.start) 10h06 <= (a.end) 10h09 ==> test vrai
    (2) --> (b.start) 10h06 <= (a.end) 10h09 <= (b.end) 10h07 ==> test faux
    donc vrai !

    Tandis que pour le deuxième exemple, c'est le test (2) qui fonctionne :
    (1) --> (a.start) 10h06 <= (b.start) 10h05 <= (a.end) 10h07 ==> test faux
    (2) --> (b.start) 10h05 <= (a.end) 10h07 <= (b.end) 10h09 ==> test vrai
    donc vrai !

    Et donc dans vos deux exemples, les tests sont vrai.

    Je reconnais que le test de Hilal74 qu voici est plus simple :
    (3) --> a.start <= b.end
    (4) --> b.start <= a.end
    dont la condition est (3) ET (4) !

    Pour le premier exemple, nous avons :
    (3) --> (a.start) 10h05 <= (b.end) 10h07 ==> test vrai
    (4) --> (b.start) 10h06 <= (a.end) 10h09 ==> test vrai
    donc vrai !

    Dans le deuxième exemple, nous avons :
    (3) --> (a.start) 10h06 <= (b.end) 10h09 ==> test vrai
    (4) --> (b.start) 10h05 <= (a.end) 10h07 ==> test vrai
    donc vrai !

    Mais si nous avons cet exemple :
    A : de 10h04 à 10h03 <== le test élémentaire est faux !
    B : de 10h02 à 10h05
    Oui, j'ai volontairement mis une heure plus petite pour a.end vis-à-vis de a.start.

    Pour mon test cela donne :
    (1) --> (a.start) 10h04 <= (b.start) 10h04 <= (a.end) 10h03 ==> test faux
    (2) --> (b.start) 10h04 <= (a.end) 10h03 <= (b.end) 10h07 ==> test faux
    donc faux !

    Et pour le test de Hilal74 cela donne :
    (3) --> (a.start) 10h04 <= (b.end) 10h05
    (4) --> (b.start) 10h02 <= (a.end) 10h03
    donc vrai !
    Or le résultat du test de Hilal74 n'est pas correcte.

    Si j'ai fait tout ce laïus, c'est juste pour indiquer que nous ne savons pas si les tests élémentaires ont été fait !
    --> a.start <= a.end
    --> b.start <= b.end

    S'ils ont été fait alors le test de Hilal74 est mieux que le mien. Sinon mon test est meilleur !

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  10. #30
    Expert éminent Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    février 2011
    Messages
    2 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : février 2011
    Messages : 2 903
    Points : 8 557
    Points
    8 557

    Par défaut

    Salut halal74.

    Citation Envoyé par halal74
    La derniere structure est la bonne, j'ai bien un starttime et un stoptime. Désole, j'ai négligé cette information car je ne pensais pas qu'elle allait avoir une importance dans le partionnement.
    Vous faites la même erreur que d'autres qui ont déposé un sujet.
    Vous simplifiez à l'extrême votre problème en croyant que cela n'a aucun importance.
    Et au final, nous sommes obligé de revoir de font en comble la problématique pour tenir compte des particularité que vous avez oublié de nous communiquer !

    Citation Envoyé par halal74
    Je pense que le fait d'utiliser la colonne starttime pour le partitionnement fera l'affaire, ainsi mes tickets seront divises par mois.
    Je ne peux pas répondre à cette question car vous êtes le seul à savoir y répondre.
    Autrement dit, j'attends quelque chose du genre aussi bien pour le ticket 'a' et le ticket 'b' :
    --> 2017-07-01 00:00:00 <= start <= end <= 2017-07-31 23:59:59

    Vous ne pouvez pas avoir par exemple :
    --> 2017-07-01 00:00:00 <= a.start <= a.end <= 2017-07-31 23:59:59
    --> 2017-08-01 00:00:00 <= b.start <= b.end <= 2017-08-31 23:59:59
    car dans ce cas là, on ne pourra pas mettre le ticket 'a' en relation avec le ticket 'b'.

    Citation Envoyé par halal74
    Il faut voir ces événèments comme des appels téléphoniques et un appel aura deux tickets de type différent, ces tickets (A et B) apportent des informations complémentaires a l'appel.
    Et donc, le ticket 'A' et le ticket 'B' qui lui est associé seront toujours définies dans la même journée.
    A moins que vous recevez des appels entre 23h00 et 01h00, c'est-à-dire à cheval sur deux jours et par conséquence aussi sur deux mois, voire aussi sur deux années.
    Je sais que c'est un cas extrême, mais il faut l'envisager ou pas. A vous de me répondre.

    Citation Envoyé par halal74
    On a deux tickets car ces informations viennent de deux sources différentes et ces tickets sont lies par le canal a.canal=b.canal et a.startEvent < b.StopEvent and a.StopEvent > b.StartEvent (car c'est le même appel).
    Je suppose que le canal c'est en fait un téléphone. Et vous ne pouvez pas recevoir deux appels dans le même intervalle de temps.
    Je sais que la question semble idiote mais vu que je ne sais pas comment vous travaillez, je dois comprendre où se trouve la difficulté.
    Autrement dit, vous recevez des appels sur un téléphone les uns après les autres mais jamais en mettant un premier appel en attente pendant que vous traitiez un second appel.
    Puis quand le second appel est terminé vous continuez le premier appel.

    Pourquoi aussi tout ce laïus ? Un coup de téléphone aura nécessairement un seul ticket 'A' et un seul ticket 'B' dans un intervalle de temps donnée.

    Citation Envoyé par halal74
    Je placerai plus tout cela dans ma clause where
    Non, car vous aurez un problème de performance. Ici, vous traitez une jointure.
    Cela signifie que vous allez remonter toutes les lignes qui auront ce tests valide.
    Qu'est-ce que vous préférez obtenir ? 1 seule ligne (le ticket B pour le second alias si vous avez le ticket A pour le premier alirs et vice-versa) ou bien plusieurs ?

    Donc la jointure n'est pas complète. Il faut aussi ajouter votre test sur les dates, ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    inner join  maTable  as b 
            on  b.ChanalNumber  =  a.ChanalNumber
           and  b.TypEvent      = case when a.TypEvent = 'a' then 'b' else 'a' end
           and  b.Stop_Event   >= a.Start_Event
           and  a.Stop_Event   >= b.Start_Event
           and  b.Start_Event  between '2015-01-01 00:00:00' and '2015-01-31 23:59:59';
    Il faudra certainement ajouter aussi le test sur la sélection de la partition.
    Et si vous désirez obtenir la même extraction, il faudra envisager une seconde requête sur la période du mois de février 2015.

    Citation Envoyé par halal74
    Je partirai plutot sur une clause where comme mentionne ci dessus. Qu'en pensez vous?
    Non ! Dans une jointure, on met ce qui est en relation entre la table supérieure et celle de votre jointure (inner join).

    Dans le where, on met ce que ne fait pas partie de la jointure, et donc les restrictions sur la première table (celle du from).
    Pour l'instant, je ne vois que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    where a.Start_Event  between '2015-01-01 00:00:00' and '2015-01-31 23:59:59'
    Citation Envoyé par halal74
    En fait j'ai essaye d'ajouter un index compose de plusieurs colonnes mais cela n'a fait qu'augmenter le temps d’exécution. Dans cette index j'ai mis (StartEvent, StopEvent, ChannelEvent, TypEvent), comment puis identifier la colonne qui a ralenti ma requete?
    Vous devez créez autant d'index que vous avez de tables dans votre requêtes.
    Dans votre requête, vous avez deux tables, l'une en from et l'autre en jointure (inner join).
    Plus précisément, l'un des index sera en relation avec la condition de la jointure et l'autre avec le where.

    Je vais compléter mon script de test et je vous le communiquerai un peu plus tard.
    Etes-vous fâché avec les accents ?

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  11. #31
    Membre à l'essai
    Inscrit en
    mai 2009
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : mai 2009
    Messages : 42
    Points : 21
    Points
    21

    Par défaut

    Salut Artemus24,

    Non je ne suis pas fache avec les accents j'utilise un clavier qwerty je vis dans un pays Anglo saxon.

    Je suis vraiment desole pour le manque de precision je comprends que cela puisse compliquer la tache. J'y preterai attention pour la prochaine fois.

    Ce que je ne comprends pas ( je reitere ma question posee a tbc92) pourquoi quand j'ajoute un index que ce soit avec la colonne Channel/type/... cela ralenti encore plus au lieu d'augmenter la performance or si je fais un simple select avec une clause

    where sur Channel par exemple je vois bien la difference de performance en rajoutant l'index. Est ce du au fait que dans ma jointure j'utilise la meme table et donc les colonnes sont partagees.

    Merci

  12. #32
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    décembre 2013
    Messages
    1 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : décembre 2013
    Messages : 1 455
    Points : 3 039
    Points
    3 039

    Par défaut

    Et je réitère ma réponse, en la complétant. Les statistiques sur les index, ça peut être important.
    Tu peux aussi rechercher "hints index mysql", tu trouveras des trucs pour aider Mysql à prendre les bonnes décisions. (je ne suis pas sur que ce soit un bon conseil, MySQL est peut être plus rusé que toi !)
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  13. #33
    Expert éminent Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    février 2011
    Messages
    2 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : février 2011
    Messages : 2 903
    Points : 8 557
    Points
    8 557

    Par défaut

    Salut hilal74.

    Voici ce que je propose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE IF NOT EXISTS `base`
        DEFAULT CHARACTER SET `latin1`
        DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `ticket_A`
    --------------
     
    --------------
    CREATE TABLE `ticket_A`
    ( `a_canal`       integer unsigned  NOT NULL,
      `a_start_date`  date              NOT NULL,
      `a_start_time`  time              NOT NULL,
      `a_end_date`    date              NOT NULL,
      `a_end_time`    time              NOT NULL,
      `a_agent`       varchar(255)      NOT NULL,
     
      PRIMARY KEY  (`a_canal`,`a_start_date`,`a_end_date`,`a_start_time`,`a_end_time`)
    ) ENGINE=Innodb
      ROW_FORMAT=COMPRESSED
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      PARTITION BY HASH (year(a_start_date) * 12 + month(a_start_date))
      Partitions 25
    --------------
     
    --------------
    insert into `ticket_A` (`a_start_date`,`a_start_time`,`a_end_date`,`a_end_time`,`a_canal`,`a_agent`) values
      ('2015-05-12', '17:32:00', '2015-05-12', '17:36:00', 13, 'agent 001'),
      ('2015-07-08', '14:00:00', '2015-07-08', '14:13:00', 17, 'agent 002'),
     
      ('2015-08-08', '13:27:00', '2015-08-08', '13:30:00', 12, 'agent 003'),
      ('2015-08-08', '13:32:00', '2015-08-08', '13:35:00', 12, 'agent 003'),
      ('2015-08-08', '13:38:00', '2015-08-08', '13:41:00', 12, 'agent 003'),
      ('2015-08-08', '13:44:00', '2015-08-08', '13:52:00', 12, 'agent 003'),
      ('2015-08-08', '14:01:00', '2015-08-08', '14:17:00', 12, 'agent 003'),
     
      ('2015-08-10', '15:00:00', '2015-08-10', '15:11:00', 13, 'agent 001'),
      ('2015-08-10', '15:19:00', '2015-08-10', '15:25:00', 13, 'agent 001'),
      ('2015-08-10', '15:28:00', '2015-08-10', '15:33:00', 13, 'agent 001'),
      ('2015-08-10', '15:37:00', '2015-08-10', '15:42:00', 13, 'agent 001'),
      ('2015-08-10', '15:48:00', '2015-08-10', '15:57:00', 13, 'agent 001')
    --------------
     
    --------------
    commit
    --------------
     
    --------------
    select * from `ticket_A`
    --------------
     
    +---------+--------------+--------------+------------+------------+-----------+
    | a_canal | a_start_date | a_start_time | a_end_date | a_end_time | a_agent   |
    +---------+--------------+--------------+------------+------------+-----------+
    |      13 | 2015-05-12   | 17:32:00     | 2015-05-12 | 17:36:00   | agent 001 |
    |      17 | 2015-07-08   | 14:00:00     | 2015-07-08 | 14:13:00   | agent 002 |
    |      12 | 2015-08-08   | 13:27:00     | 2015-08-08 | 13:30:00   | agent 003 |
    |      12 | 2015-08-08   | 13:32:00     | 2015-08-08 | 13:35:00   | agent 003 |
    |      12 | 2015-08-08   | 13:38:00     | 2015-08-08 | 13:41:00   | agent 003 |
    |      12 | 2015-08-08   | 13:44:00     | 2015-08-08 | 13:52:00   | agent 003 |
    |      12 | 2015-08-08   | 14:01:00     | 2015-08-08 | 14:17:00   | agent 003 |
    |      13 | 2015-08-10   | 15:00:00     | 2015-08-10 | 15:11:00   | agent 001 |
    |      13 | 2015-08-10   | 15:19:00     | 2015-08-10 | 15:25:00   | agent 001 |
    |      13 | 2015-08-10   | 15:28:00     | 2015-08-10 | 15:33:00   | agent 001 |
    |      13 | 2015-08-10   | 15:37:00     | 2015-08-10 | 15:42:00   | agent 001 |
    |      13 | 2015-08-10   | 15:48:00     | 2015-08-10 | 15:57:00   | agent 001 |
    +---------+--------------+--------------+------------+------------+-----------+
    --------------
    SELECT  PARTITION_NAME
      FROM  INFORMATION_SCHEMA.PARTITIONS
      WHERE TABLE_SCHEMA = 'base'
        AND TABLE_NAME   = 'ticket_A'
        AND TABLE_ROWS   <> 0
    --------------
     
    +----------------+
    | PARTITION_NAME |
    +----------------+
    | p10            |
    | p12            |
    | p13            |
    +----------------+
    --------------
    select * from `ticket_A` partition (p10)
    --------------
     
    +---------+--------------+--------------+------------+------------+-----------+
    | a_canal | a_start_date | a_start_time | a_end_date | a_end_time | a_agent   |
    +---------+--------------+--------------+------------+------------+-----------+
    |      13 | 2015-05-12   | 17:32:00     | 2015-05-12 | 17:36:00   | agent 001 |
    +---------+--------------+--------------+------------+------------+-----------+
    --------------
    select * from `ticket_A` partition (p12)
    --------------
     
    +---------+--------------+--------------+------------+------------+-----------+
    | a_canal | a_start_date | a_start_time | a_end_date | a_end_time | a_agent   |
    +---------+--------------+--------------+------------+------------+-----------+
    |      17 | 2015-07-08   | 14:00:00     | 2015-07-08 | 14:13:00   | agent 002 |
    +---------+--------------+--------------+------------+------------+-----------+
    --------------
    select * from `ticket_A` partition (p13)
    --------------
     
    +---------+--------------+--------------+------------+------------+-----------+
    | a_canal | a_start_date | a_start_time | a_end_date | a_end_time | a_agent   |
    +---------+--------------+--------------+------------+------------+-----------+
    |      12 | 2015-08-08   | 13:27:00     | 2015-08-08 | 13:30:00   | agent 003 |
    |      12 | 2015-08-08   | 13:32:00     | 2015-08-08 | 13:35:00   | agent 003 |
    |      12 | 2015-08-08   | 13:38:00     | 2015-08-08 | 13:41:00   | agent 003 |
    |      12 | 2015-08-08   | 13:44:00     | 2015-08-08 | 13:52:00   | agent 003 |
    |      12 | 2015-08-08   | 14:01:00     | 2015-08-08 | 14:17:00   | agent 003 |
    |      13 | 2015-08-10   | 15:00:00     | 2015-08-10 | 15:11:00   | agent 001 |
    |      13 | 2015-08-10   | 15:19:00     | 2015-08-10 | 15:25:00   | agent 001 |
    |      13 | 2015-08-10   | 15:28:00     | 2015-08-10 | 15:33:00   | agent 001 |
    |      13 | 2015-08-10   | 15:37:00     | 2015-08-10 | 15:42:00   | agent 001 |
    |      13 | 2015-08-10   | 15:48:00     | 2015-08-10 | 15:57:00   | agent 001 |
    +---------+--------------+--------------+------------+------------+-----------+
    --------------
    DROP TABLE IF EXISTS `ticket_B`
    --------------
     
    --------------
    CREATE TABLE `ticket_B`
    ( `b_canal`       integer unsigned  NOT NULL,
      `b_start_date`  date              NOT NULL,
      `b_start_time`  time              NOT NULL,
      `b_end_date`    date              NOT NULL,
      `b_end_time`    time              NOT NULL,
      `b_telephone`   varchar(255)      NOT NULL,
     
      PRIMARY KEY  (`b_canal`,`b_start_date`,`b_end_date`,`b_start_time`,`b_end_time`)
    ) ENGINE=Innodb
      ROW_FORMAT=COMPRESSED
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      PARTITION BY HASH (year(b_start_date) * 12 + month(b_start_date))
      Partitions 25
    --------------
     
    --------------
    insert into `ticket_B` (`b_start_date`,`b_start_time`,`b_end_date`,`b_end_time`,`b_canal`,`b_telephone`) values
      ('2015-05-12', '17:33:00', '2015-05-12', '17:37:00', 13, '01 23 45 67 89'),
      ('2015-07-08', '14:02:00', '2015-07-08', '14:15:00', 17, '01 98 76 54 32'),
     
      ('2015-08-08', '13:28:00', '2015-08-08', '13:31:00', 12, '01 32 54 76 98'),
      ('2015-08-10', '15:30:00', '2015-08-10', '15:35:00', 13, '01 44 55 66 77'),
      ('2015-08-08', '13:33:00', '2015-08-08', '13:36:00', 12, '01 45 89 23 67'),
      ('2015-08-10', '15:39:00', '2015-08-10', '15:44:00', 13, '01 78 32 98 54'),
      ('2015-08-08', '13:39:00', '2015-08-08', '13:43:00', 12, '01 33 44 55 66'),
      ('2015-08-10', '15:50:00', '2015-08-10', '15:58:00', 13, '01 66 77 88 99'),
      ('2015-08-08', '13:45:00', '2015-08-08', '13:53:00', 12, '01 11 22 33 44'),
      ('2015-08-10', '15:02:00', '2015-08-10', '15:12:00', 13, '01 89 67 45 23'),
      ('2015-08-08', '14:03:00', '2015-08-08', '14:18:00', 12, '01 55 66 77 88'),
      ('2015-08-10', '15:21:00', '2015-08-10', '15:27:00', 13, '01 22 33 44 55')
    --------------
     
    --------------
    commit
    --------------
     
    --------------
    select * from `ticket_B`
    --------------
     
    +---------+--------------+--------------+------------+------------+----------------+
    | b_canal | b_start_date | b_start_time | b_end_date | b_end_time | b_telephone    |
    +---------+--------------+--------------+------------+------------+----------------+
    |      13 | 2015-05-12   | 17:33:00     | 2015-05-12 | 17:37:00   | 01 23 45 67 89 |
    |      17 | 2015-07-08   | 14:02:00     | 2015-07-08 | 14:15:00   | 01 98 76 54 32 |
    |      12 | 2015-08-08   | 13:28:00     | 2015-08-08 | 13:31:00   | 01 32 54 76 98 |
    |      12 | 2015-08-08   | 13:33:00     | 2015-08-08 | 13:36:00   | 01 45 89 23 67 |
    |      12 | 2015-08-08   | 13:39:00     | 2015-08-08 | 13:43:00   | 01 33 44 55 66 |
    |      12 | 2015-08-08   | 13:45:00     | 2015-08-08 | 13:53:00   | 01 11 22 33 44 |
    |      12 | 2015-08-08   | 14:03:00     | 2015-08-08 | 14:18:00   | 01 55 66 77 88 |
    |      13 | 2015-08-10   | 15:02:00     | 2015-08-10 | 15:12:00   | 01 89 67 45 23 |
    |      13 | 2015-08-10   | 15:21:00     | 2015-08-10 | 15:27:00   | 01 22 33 44 55 |
    |      13 | 2015-08-10   | 15:30:00     | 2015-08-10 | 15:35:00   | 01 44 55 66 77 |
    |      13 | 2015-08-10   | 15:39:00     | 2015-08-10 | 15:44:00   | 01 78 32 98 54 |
    |      13 | 2015-08-10   | 15:50:00     | 2015-08-10 | 15:58:00   | 01 66 77 88 99 |
    +---------+--------------+--------------+------------+------------+----------------+
    --------------
    SELECT  PARTITION_NAME
      FROM  INFORMATION_SCHEMA.PARTITIONS
      WHERE TABLE_SCHEMA = 'base'
        AND TABLE_NAME   = 'ticket_B'
        AND TABLE_ROWS <> 0
    --------------
     
    +----------------+
    | PARTITION_NAME |
    +----------------+
    | p10            |
    | p12            |
    | p13            |
    +----------------+
    --------------
    select * from `ticket_B` partition (p10)
    --------------
     
    +---------+--------------+--------------+------------+------------+----------------+
    | b_canal | b_start_date | b_start_time | b_end_date | b_end_time | b_telephone    |
    +---------+--------------+--------------+------------+------------+----------------+
    |      13 | 2015-05-12   | 17:33:00     | 2015-05-12 | 17:37:00   | 01 23 45 67 89 |
    +---------+--------------+--------------+------------+------------+----------------+
    --------------
    select * from `ticket_B` partition (p12)
    --------------
     
    +---------+--------------+--------------+------------+------------+----------------+
    | b_canal | b_start_date | b_start_time | b_end_date | b_end_time | b_telephone    |
    +---------+--------------+--------------+------------+------------+----------------+
    |      17 | 2015-07-08   | 14:02:00     | 2015-07-08 | 14:15:00   | 01 98 76 54 32 |
    +---------+--------------+--------------+------------+------------+----------------+
    --------------
    select * from `ticket_B` partition (p13)
    --------------
     
    +---------+--------------+--------------+------------+------------+----------------+
    | b_canal | b_start_date | b_start_time | b_end_date | b_end_time | b_telephone    |
    +---------+--------------+--------------+------------+------------+----------------+
    |      12 | 2015-08-08   | 13:28:00     | 2015-08-08 | 13:31:00   | 01 32 54 76 98 |
    |      12 | 2015-08-08   | 13:33:00     | 2015-08-08 | 13:36:00   | 01 45 89 23 67 |
    |      12 | 2015-08-08   | 13:39:00     | 2015-08-08 | 13:43:00   | 01 33 44 55 66 |
    |      12 | 2015-08-08   | 13:45:00     | 2015-08-08 | 13:53:00   | 01 11 22 33 44 |
    |      12 | 2015-08-08   | 14:03:00     | 2015-08-08 | 14:18:00   | 01 55 66 77 88 |
    |      13 | 2015-08-10   | 15:02:00     | 2015-08-10 | 15:12:00   | 01 89 67 45 23 |
    |      13 | 2015-08-10   | 15:21:00     | 2015-08-10 | 15:27:00   | 01 22 33 44 55 |
    |      13 | 2015-08-10   | 15:30:00     | 2015-08-10 | 15:35:00   | 01 44 55 66 77 |
    |      13 | 2015-08-10   | 15:39:00     | 2015-08-10 | 15:44:00   | 01 78 32 98 54 |
    |      13 | 2015-08-10   | 15:50:00     | 2015-08-10 | 15:58:00   | 01 66 77 88 99 |
    +---------+--------------+--------------+------------+------------+----------------+
    --------------
    explain
    select       t1.a_start_date, t1.a_start_time, t1.a_end_date, t1.a_end_time, t1.a_canal, t1.a_agent,
                 t2.b_start_date, t2.b_start_time, t2.b_end_date, t2.b_end_time, t2.b_canal, t2.b_telephone
     
           from  `ticket_A` partition (p13) as t1
     
     inner join  `ticket_B` partition (p13) as t2
     
             on  t2.b_canal       = t1.a_canal
            and  t2.b_start_date  = t1.a_start_date
            and  t2.b_end_date    = t1.a_end_date
     
            and  t2.b_start_time <= t1.a_end_time
            and  t2.b_end_time   >= t1.a_start_time
     
       order by  t1.a_start_date, t1.a_start_time
    --------------
     
    +----+-------------+-------+------------+------+---------------+---------+---------+---------------------------------------------------------+------+----------+----------------+
    | id | select_type | table | partitions | type | possible_keys | key     | key_len | ref                                                     | rows | filtered | Extra          |
    +----+-------------+-------+------------+------+---------------+---------+---------+---------------------------------------------------------+------+----------+----------------+
    |  1 | SIMPLE      | t1    | p13        | ALL  | PRIMARY       | NULL    | NULL    | NULL                                                    |    9 |   100.00 | Using filesort |
    |  1 | SIMPLE      | t2    | p13        | ref  | PRIMARY       | PRIMARY | 10      | base.t1.a_canal,base.t1.a_start_date,base.t1.a_end_date |    1 |    11.11 | Using where    |
    +----+-------------+-------+------------+------+---------------+---------+---------+---------------------------------------------------------+------+----------+----------------+
    --------------
    select       t1.a_start_date, t1.a_start_time, t1.a_end_date, t1.a_end_time, t1.a_canal, t1.a_agent,
                 t2.b_start_date, t2.b_start_time, t2.b_end_date, t2.b_end_time, t2.b_canal, t2.b_telephone
     
           from  `ticket_A` partition (p13) as t1
     
     inner join  `ticket_B` partition (p13) as t2
     
             on  t2.b_canal       = t1.a_canal
            and  t2.b_start_date  = t1.a_start_date
            and  t2.b_end_date    = t1.a_end_date
     
            and  t2.b_start_time <= t1.a_end_time
            and  t2.b_end_time   >= t1.a_start_time
     
       order by  t1.a_start_date, t1.a_start_time
    --------------
     
    +--------------+--------------+------------+------------+---------+-----------+--------------+--------------+------------+------------+---------+----------------+
    | a_start_date | a_start_time | a_end_date | a_end_time | a_canal | a_agent   | b_start_date | b_start_time | b_end_date | b_end_time | b_canal | b_telephone    |
    +--------------+--------------+------------+------------+---------+-----------+--------------+--------------+------------+------------+---------+----------------+
    | 2015-08-08   | 13:27:00     | 2015-08-08 | 13:30:00   |      12 | agent 003 | 2015-08-08   | 13:28:00     | 2015-08-08 | 13:31:00   |      12 | 01 32 54 76 98 |
    | 2015-08-08   | 13:32:00     | 2015-08-08 | 13:35:00   |      12 | agent 003 | 2015-08-08   | 13:33:00     | 2015-08-08 | 13:36:00   |      12 | 01 45 89 23 67 |
    | 2015-08-08   | 13:38:00     | 2015-08-08 | 13:41:00   |      12 | agent 003 | 2015-08-08   | 13:39:00     | 2015-08-08 | 13:43:00   |      12 | 01 33 44 55 66 |
    | 2015-08-08   | 13:44:00     | 2015-08-08 | 13:52:00   |      12 | agent 003 | 2015-08-08   | 13:45:00     | 2015-08-08 | 13:53:00   |      12 | 01 11 22 33 44 |
    | 2015-08-08   | 14:01:00     | 2015-08-08 | 14:17:00   |      12 | agent 003 | 2015-08-08   | 14:03:00     | 2015-08-08 | 14:18:00   |      12 | 01 55 66 77 88 |
    | 2015-08-10   | 15:00:00     | 2015-08-10 | 15:11:00   |      13 | agent 001 | 2015-08-10   | 15:02:00     | 2015-08-10 | 15:12:00   |      13 | 01 89 67 45 23 |
    | 2015-08-10   | 15:19:00     | 2015-08-10 | 15:25:00   |      13 | agent 001 | 2015-08-10   | 15:21:00     | 2015-08-10 | 15:27:00   |      13 | 01 22 33 44 55 |
    | 2015-08-10   | 15:28:00     | 2015-08-10 | 15:33:00   |      13 | agent 001 | 2015-08-10   | 15:30:00     | 2015-08-10 | 15:35:00   |      13 | 01 44 55 66 77 |
    | 2015-08-10   | 15:37:00     | 2015-08-10 | 15:42:00   |      13 | agent 001 | 2015-08-10   | 15:39:00     | 2015-08-10 | 15:44:00   |      13 | 01 78 32 98 54 |
    | 2015-08-10   | 15:48:00     | 2015-08-10 | 15:57:00   |      13 | agent 001 | 2015-08-10   | 15:50:00     | 2015-08-10 | 15:58:00   |      13 | 01 66 77 88 99 |
    +--------------+--------------+------------+------------+---------+-----------+--------------+--------------+------------+------------+---------+----------------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
    Appuyez sur une touche pour continuer...
    1) créez deux tables, l'une pour le ticket A et l'autre pour le ticket B.

    2) elles sont partitionnées sur 25 mois. Le 25 mois étant le mois courant.

    3) j'ai décomposé la colonne start en start_date et start_time. Idem pour la colonne end. Pourquoi ?
    Pour améliorer la performance car le recherche se faisait sur le mois.
    Avec cette astuce, la recherche se fait sur le jour, donc sur moins de lignes.

    4) j'ai créé une clef primaire contenant les colonnes suivantes :
    --> canal
    --> start_date
    --> end_date
    --> start_time
    --> end_time

    Seule les trois premières colonnes sont prises pour l'association index et test de jointure basées sur l'égalité.

    5) j'ai mis une requête en explain afin de montrer le résultat de la recherche. On voit que la clef primaire a été utilisées.

    6) la requête ne traite qu'une seule partition à la fois, c'est-à-dire 1 mois.

    7) pour calculer la répartition des lignes dans les partitions, j'ai utilisé l'astuce suivante :
    --> year(start_date) * 12 + month(start_date).
    La répartition se fera en fonction du modulo 25 du calcul précédent.

    Ainsi pour la date 2017-05, le calcul donnera :
    --> 2017 * 12 + 5 = 24209
    --> 24209 modulo 25 = 9
    soit la partition 9.

    8) au cas où la requête MySql ne prend pas la clef primaire, vous pouvez forcer ce choix.
    J'ai en effet mis en commentaire la ligne "force index (`primary`)", juste après la ligne contenant le "inner join".
    Désolé, mais à l'exécution, une ligne en commentaire n’apparaît pas.

    A vous de faire des tests avec cette structure, et dites nous combien de temps la requête à mis à l'exécution.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  14. #34
    Membre à l'essai
    Inscrit en
    mai 2009
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : mai 2009
    Messages : 42
    Points : 21
    Points
    21

    Par défaut

    Salut Artemus24,

    Merci, je vais suivre vos conseils et je vous tiens au courant.

  15. #35
    Membre à l'essai
    Inscrit en
    mai 2009
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : mai 2009
    Messages : 42
    Points : 21
    Points
    21

    Par défaut

    Salut Artemus24,

    J'ai utiliser un index sur les colonnes (Channel, StartTime, EndTime) cela a augmente le temps de reponse de maniere impressionante je suis passe de 18min a 12 seconde. Je n'ai pas pu les mettres dans une clee primaire du fait que les valeurs ne sont pas unique mais ce n'est pas grave ca marche tres bien avec l'index simple.
    Par contre la rapidite que je constate sur une journee n'est pas refletee sur le mois (C'est bcp trop long) donc je suis passe tout simplement a une table par jour cela me fait bcp de table mais ce n'est pas grave le resultat est rapide.
    Je vais donc creer une procedure qui va effectuer l'analyse par mois et a chaque fois creer des tables par jour Table_TypeA_day1,......,Table_TypeB_day31 et Table_TypeB_day1,....,Table_TypeB_day31 effectuer l'analyse et passer au mois suivant ainsi de suite.
    Si vous avez des remarques des suggestions sur cette demarche n'hesitez pas.

    Merci.

  16. #36
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    décembre 2013
    Messages
    1 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : décembre 2013
    Messages : 1 455
    Points : 3 039
    Points
    3 039

    Par défaut

    Je te disais (message n°26) qu'en créant un index sur Type+Chanel+Start+End, tu diviserais le temps par 100. Tu as divisé le temps par 90 avec Chanel+Start+End... je suis curieux de voir ce que ça donnerait avec Type+Chanel+Start+End.
    Disons entre 6 et 9 sec, pour donner une fourchette ?
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  17. #37
    Membre à l'essai
    Inscrit en
    mai 2009
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : mai 2009
    Messages : 42
    Points : 21
    Points
    21

    Par défaut

    Salut tbc92,

    En fait j'ai cree deux tables une avec le type A et une autre avec le type B donc je n'ai plus besoin d'indexer la colonne Type.

    Merci

  18. #38
    Expert éminent

    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    2 980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 2 980
    Points : 6 533
    Points
    6 533
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par Hilal74 Voir le message
    Salut tbc92,

    En fait j'ai cree deux tables une avec le type A et une autre avec le type B donc je n'ai plus besoin d'indexer la colonne Type.

    Merci
    bonsoir,

    Si le DDL des deux tables est strictement identique et doit le rester, alors il aurait été plus simple de partitionner la table sur le critère Type et non de faire deux tables, car votre solution
    - implique une double maintenance à chaque évolution de la table (voire triple, quadruple... autant de fois qu'il y a de valeurs de type)
    - implique un impact sur les requêtes qui n'avait pas lieux d'être
    - n'apporte aucun confort supplémentaire, même terme de servitudes, puisque le partitionnement gère deux espaces de stockages strictement distincts mais avec une description unique

  19. #39
    Expert éminent Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    février 2011
    Messages
    2 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : février 2011
    Messages : 2 903
    Points : 8 557
    Points
    8 557

    Par défaut

    Salut à tous.

    Citation Envoyé par Hilal74
    je suis passe de 18min a 12 seconde.
    Petite précision de votre part, 18 minutes, est-ce avec index sur le mois ?

    Citation Envoyé par Hilal74
    Par contre la rapidite que je constate sur une journee n'est pas refletee sur le mois
    Gross modo, un mois c'est trente jours. Donc 18 * 60 / 30 = 36 secondes.
    Or vous trouvez 12 secondes, donc a priori, le traitement mensuel, ramené à la journée est trois fois plus long.

    Citation Envoyé par Hilal74
    donc je suis passe tout simplement a une table par jour
    Ce n'est pas une bonne idée.
    Il suffisait d'ahouter une contrainte supplémentaire dans la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    where t1.a_start_date = '2017-08-05'
      and t1.a_end_date   = '2017-08-05';
    Citation Envoyé par Hilal74
    Si vous avez des remarques des suggestions sur cette demarche n'hesitez pas.
    Il existe une autre approche, qui à mon avis sera plus rapide, en tout cas sur la requête d'extraction des résultats que vous recherchez.
    Par contre, l'insertion sera légèrement plus longue.

    Pour ce faire, vous devez utiliser un déclencheur (trigger) qui va remplir votre table "ticket_b" (ou l'autre table), en recherchant dans la journée afin de faire le lien entre vos deux tickets.
    Mais cela nécessite d'utiliser une clef étrangère, qui ne fonctionne pas avec les tables partitionnées.

    En formulant le problème différemment, préférez-vous perdre du temps à l'insertion ou bien lors de la requête ?
    A l'insertion, je ne sais pas trop comment arrive les tickets, mais si "ticket_A" arrive avant "ticket_B", on peut le faire au fil de l'eau.
    Sinon, un batch durant la nuit quand tous les tickets sont disponibles.

    Citation Envoyé par Escartefigue
    Si le DDL des deux tables est strictement identique et doit le rester
    Non, car si la table a plusieurs colonnes communes, ce n'est pas le cas pour les autres colonnes.
    Dans mon exemple, la différence entre les tables "ticket_A" et "ticket_B" repose sur les colonnes "a_agent" et "b_telephone".

    Dans le cas contraire, oui, j'aurai été d'accord avec vous.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  20. #40
    Membre à l'essai
    Inscrit en
    mai 2009
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : mai 2009
    Messages : 42
    Points : 21
    Points
    21

    Par défaut

    Salut Artemus24, Escartefigue,

    En fait la base de donnees que j'analyse n'est pas en production, j'utilise une sauvegarde que j'importe dans un serveur de test pour l'analyser.
    Les 18 min d'executions (analyse sur une journee) sont obtenues avec la table d'origine c'est a dire sans index mais meme en utilisant les indexes sur cette table cela n'ameliore pas les performances. J'ai constate une grande amelioration de la performance quand je suis passe sur deux tables (table type_A et table type_B) avec les indexes et la je suis passe a 12 secondes (analyse sur une journee).



    Merci

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. lancer un job uniquement si une table mysql contient des donnees
    Par jj4822 dans le forum Développement de jobs
    Réponses: 7
    Dernier message: 13/10/2014, 09h58
  2. Réponses: 5
    Dernier message: 20/10/2013, 03h09
  3. Fichier XML qui remplit une table MySQL + pb d'accent
    Par sheira dans le forum PHP & MySQL
    Réponses: 5
    Dernier message: 17/09/2010, 10h01
  4. interrogation d'une table MYSQL qui ne marche pas
    Par laurentSc dans le forum Débuter
    Réponses: 11
    Dernier message: 01/02/2010, 22h24
  5. Réponses: 23
    Dernier message: 22/10/2008, 17h31

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