Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1124 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [résolu] Problème de requête, CPU à 100%...

 



 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

[résolu] Problème de requête, CPU à 100%...

n°1160368
RaTo
Posté le 26-07-2005 à 15:12:51  profilanswer
 

Je dois écrire une requête qui me retourne la liste des personnes non connectées depuis 1 mois (à un réseau).
La requête que j'ai écris :

SELECT * FROM historique_login WHERE login_loginname NOT IN (SELECT login_loginname FROM historique_login WHERE login_timestamp > (NOW( ) - INTERVAL 1 MONTH ))


 
Quand je lance la requête dans phpMyAdmin, la page se charge très lentement et se bloque. Je n'arrive pas à afficher de résultats. Le processus mysqld-nt.exe consomme à ce moment 99% du CPU et met longtemps à redescendre, même quand je tente d'arrêter l'exécution de la requête.
 
Qu'est-ce qui cloche dans cette requête ?  :??:


Message édité par RaTo le 27-07-2005 à 11:28:08
mood
Publicité
Posté le 26-07-2005 à 15:12:51  profilanswer
 

n°1160370
skeye
Posté le 26-07-2005 à 15:17:55  profilanswer
 

Tu peux pas la faire sans sous-requête?[:mlc]
du style:
select * from historique_login where login_timestamp < (NOW( ) - INTERVAL 1 MONTH )  
 
[:dawa]


---------------
Can't buy what I want because it's free -
n°1160371
Beegee
Posté le 26-07-2005 à 15:18:03  profilanswer
 

Remplace le NOT IN par un NOT EXISTS pour voir.
 

Code :
  1. SELECT *
  2. FROM historique_login hl
  3. WHERE NOT EXISTS
  4. (SELECT 1
  5. FROM historique_login
  6. WHERE login_loginname = hl.login_loginname
  7. AND login_timestamp > (NOW( ) - INTERVAL 1 MONTH ));

n°1160372
skeye
Posté le 26-07-2005 à 15:18:33  profilanswer
 

Beegee a écrit :

Remplace le NOT IN par un NOT EXISTS pour voir.
 

Code :
  1. SELECT *
  2. FROM historique_login hl
  3. WHERE NOT EXISTS
  4. (SELECT 1
  5. FROM historique_login
  6. WHERE login_loginname = hl.login_loginname
  7. AND login_timestamp > (NOW( ) - INTERVAL 1 MONTH ));



Mais [:ktulu] !


---------------
Can't buy what I want because it's free -
n°1160373
Beegee
Posté le 26-07-2005 à 15:19:08  profilanswer
 

skeye a écrit :

Tu peux pas la faire sans sous-requête?[:mlc]
du style:
select * from historique_login where login_timestamp < (NOW( ) - INTERVAL 1 MONTH )  
 
[:dawa]


 
Ben non, vu sa demande, il veut pas voir les utilisateurs qui se sont connectés durant le dernier mois ;)

n°1160374
skeye
Posté le 26-07-2005 à 15:19:47  profilanswer
 

Beegee a écrit :

Ben non, vu sa demande, il veut pas voir les utilisateurs qui se sont connectés durant le dernier mois ;)


c'est pas ce que j'ai écrit?


---------------
Can't buy what I want because it's free -
n°1160380
Beegee
Posté le 26-07-2005 à 15:20:54  profilanswer
 

Non, tu sélectionnes l'historique de plus d'un mois de tous les utilisateurs.
 
Ce n'est pas la même chose que l'historique complet des utilisateurs non connectés durant le dernier mois.

n°1160389
RaTo
Posté le 26-07-2005 à 15:25:11  profilanswer
 

Beegee a écrit :

Non, tu sélectionnes l'historique de plus d'un mois de tous les utilisateurs.
 
Ce n'est pas la même chose que l'historique complet des utilisateurs non connectés durant le dernier mois.


 
Exactement.  :jap:  
 
Sinon en remplaçant le NOT IN par NOT EXISTS j'ai une erreur de syntaxe :
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'EXISTS (SELECT login_loginname FROM historique_login WHERE login_timestamp > (NO' at line 1  
 

n°1160390
skeye
Posté le 26-07-2005 à 15:25:14  profilanswer
 

Beegee a écrit :

Non, tu sélectionnes l'historique de plus d'un mois de tous les utilisateurs.
 
Ce n'est pas la même chose que l'historique complet des utilisateurs non connectés durant le dernier mois.


 
ah oui.
Ca empêche pas de le faire sans sous-requête.:o
 
select max(login_timestamp), champ2, champ3
from historique_login
where login_timestamp < (NOW( ) - INTERVAL 1 MONTH )
group by (champ2, champ3)
 
:o
 
[edit]
 
encore raté...[:joce]


Message édité par skeye le 26-07-2005 à 15:25:55

---------------
Can't buy what I want because it's free -
n°1160393
megadub
Posté le 26-07-2005 à 15:26:29  profilanswer
 

bah pourquoi pas ça simplement :
 
SELECT * FROM historique_login WHERE login_timestamp <= (NOW( ) - INTERVAL 1 MONTH ))
 
Si tu supprimes les logins de plus d'un mois alors il suffit de garder ceux de moins d'un mois... comment faire simple quand on peut faire compliqué :/

mood
Publicité
Posté le 26-07-2005 à 15:26:29  profilanswer
 

n°1160397
skeye
Posté le 26-07-2005 à 15:27:17  profilanswer
 

RaTo a écrit :

Exactement.  :jap:  
 
Sinon en remplaçant le NOT IN par NOT EXISTS j'ai une erreur de syntaxe :
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'EXISTS (SELECT login_loginname FROM historique_login WHERE login_timestamp > (NO' at line 1


 
essaye d'aliaser ta table dans la requête imbriquée, aussi.


---------------
Can't buy what I want because it's free -
n°1160398
skeye
Posté le 26-07-2005 à 15:27:53  profilanswer
 

megadub a écrit :

bah pourquoi pas ça simplement :
 
SELECT * FROM historique_login WHERE login_timestamp <= (NOW( ) - INTERVAL 1 MONTH ))
 
Si tu supprimes les logins de plus d'un mois alors il suffit de garder ceux de moins d'un mois... comment faire simple quand on peut faire compliqué :/


 
Bien vu, même connerie que moi![:joce]
J'avais pas pensé non plus qu'il conservait tout son historique...[:joce]


---------------
Can't buy what I want because it's free -
n°1160406
skeye
Posté le 26-07-2005 à 15:31:57  profilanswer
 

par curiosité, ya combien de lignes dans ta table historique_login?
 
[edit]
 
Question subsidiaire : ne serait-ce pas intéressant de la transformer en dernier_login?[:joce]


Message édité par skeye le 26-07-2005 à 15:32:35

---------------
Can't buy what I want because it's free -
n°1160409
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2005 à 15:32:33  profilanswer
 

Vérifie déjà que dans ta version de MySQL y'a bien le EXISTS qui est supporté. Apparement, il ne l'est pas.
 
S'il ne supporte pas, alors change de version (super, j'adore ce SGBD :D) ou tu peux aussi d'apporter une légère optimisation à ton NOT IN en résuidant la liste qu'il retourne :
 

Code :
  1. SELECT * FROM historique_login WHERE login_loginname NOT IN (SELECT login_loginname FROM historique_login WHERE login_timestamp > (NOW( ) - INTERVAL 1 MONTH ) group by login_loginname)


 
C'est pas forcément énorme comme optimisation, mais ça devrait aider.
 
Ensuite, n'oublie pas de créer deux index :
 
historique_login(login_timestamp, login_loginname)
historique_login(login_loginname)
 
Le premier devant pouvoir être unique (en comptant qu'une personne ne se logue normalement pas deux fois dans la même milli-seconde.

n°1160410
RaTo
Posté le 26-07-2005 à 15:32:50  profilanswer
 

En balaçant la requête :

Code :
  1. SELECT *
  2. FROM historique_login hl
  3. WHERE NOT EXISTS
  4. (SELECT 1
  5. FROM historique_login
  6. WHERE login_loginname = hl.login_loginname
  7. AND login_timestamp > (NOW( ) - INTERVAL 1 MONTH ));


 
Même résultat qu'avec la mienne, plantage de mysql...

n°1160413
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2005 à 15:34:09  profilanswer
 

Teste ma solution.

n°1160414
Beegee
Posté le 26-07-2005 à 15:34:09  profilanswer
 

Autre question qui va avec : y a-t-il un index sur login_loginname ?

n°1160416
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2005 à 15:34:31  profilanswer
 

Avec les index evidement.

n°1160418
megadub
Posté le 26-07-2005 à 15:36:10  profilanswer
 

skeye a écrit :

Bien vu, même connerie que moi![:joce]
J'avais pas pensé non plus qu'il conservait tout son historique...[:joce]


 
ha oui, alors :
 

Code :
  1. SELECT login_name, max(login_timestamp) FROM historique_login WHERE login_timestamp <= (NOW( ) - INTERVAL 1 MONTH ))
  2. GROUP BY login_name


 
ça devrait le faire ça non ?

n°1160419
RaTo
Posté le 26-07-2005 à 15:36:26  profilanswer
 

skeye a écrit :

par curiosité, ya combien de lignes dans ta table historique_login?


 
22 116
 

skeye a écrit :

Question subsidiaire : ne serait-ce pas intéressant de la transformer en dernier_login?[:joce]


 
 :??:  

n°1160421
Beegee
Posté le 26-07-2005 à 15:37:17  profilanswer
 

Vu que EXISTS ne semble pas supporté, passage par jointure externe, comme d'hab' :)
 

Code :
  1. SELECT *
  2. FROM historique_login hl1
  3. LEFT JOIN  hl2 ON hl2.login_loginname = hl1.login_loginname
  4. WHERE hl2.login_timestamp > (NOW( ) - INTERVAL 1 MONTH)
  5. AND hl2.login_loginname IS NULL;


 
Il suffit d'avoir un index sur login_loginname.
 
edit: si tu veux juste les logins et que tu n'as pas besoin de l'historique, alors tu peux faire ça aussi :
 

Code :
  1. SELECT login_loginname, MAX(login_timestamp)
  2. FROM historique_login
  3. GROUP BY login_loginname
  4. HAVING MAX(login_timestamp) > (NOW( ) - INTERVAL 1 MONTH);


Message édité par Beegee le 26-07-2005 à 15:41:06
n°1160422
skeye
Posté le 26-07-2005 à 15:37:21  profilanswer
 

megadub a écrit :

ha oui, alors :
 

Code :
  1. SELECT login_name, max(login_timestamp) FROM historique_login WHERE login_timestamp <= (NOW( ) - INTERVAL 1 MONTH ))
  2. GROUP BY login_name


 
ça devrait le faire ça non ?


 
c'est le genre de trucs que j'ai proposé aussi...tu vas avoir pour tous les utilisateurs le plus récent login ayant plus d'un mois...


---------------
Can't buy what I want because it's free -
n°1160423
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2005 à 15:37:41  profilanswer
 

A mon avis, il faut surtout un group by (pour faire un distinct) dans la sous-requête.
 
En effet, même si ce sont des doublons, un NOT IN pourtant sur des milliers de valeurs, ben ça fait tout tomber. Avec un distinct, y'en aura forcément infiniment moins, et ça devrait grandement améliorer l'éxécution du NOT IN

n°1160428
skeye
Posté le 26-07-2005 à 15:39:20  profilanswer
 


Bah ça a un intérêt de garder l'historique complet de tous les logins de tes utilisateurs, en vrai?
Parce-que si non, tu gardes la date du dernier login pour chaque utilisateur, et basta...ce qui résoud aussi le pb...[:joce]


---------------
Can't buy what I want because it's free -
n°1160431
RaTo
Posté le 26-07-2005 à 15:39:51  profilanswer
 

Arjuna a écrit :

Vérifie déjà que dans ta version de MySQL y'a bien le EXISTS qui est supporté. Apparement, il ne l'est pas.


 
Je pense que le EXISTS est bien dans la version de MySQL que j'utilise, car j'arrive à faire des requêtes du style "DROP TABLE IF EXISTS..."
 
La version : 4.1.10a

n°1160435
Beegee
Posté le 26-07-2005 à 15:41:42  profilanswer
 

Je t'ai donné 2 requêtes qui devraient marcher, juste au-dessus, y a pas besoin de EXISTS de toute façon.

n°1160438
RaTo
Posté le 26-07-2005 à 15:42:43  profilanswer
 

skeye a écrit :

Bah ça a un intérêt de garder l'historique complet de tous les logins de tes utilisateurs, en vrai?

Oui. (enfin c'est une exigence de mon supérieur, donc je ne peux pas modifier ça)


Message édité par RaTo le 26-07-2005 à 15:43:33
n°1160439
megadub
Posté le 26-07-2005 à 15:43:10  profilanswer
 

skeye a écrit :

c'est le genre de trucs que j'ai proposé aussi...tu vas avoir pour tous les utilisateurs le plus récent login ayant plus d'un mois...


 
exact ;)
 

n°1160440
skeye
Posté le 26-07-2005 à 15:43:18  profilanswer
 

bon, alors voir plus haut les suggestions de beegee et arjuna...[:skeye]


---------------
Can't buy what I want because it's free -
n°1160443
skeye
Posté le 26-07-2005 à 15:44:37  profilanswer
 

Je pense que la bonne piste effectivement c'est de réduire au max le nombre de réponses de la sous-requête...


---------------
Can't buy what I want because it's free -
n°1160446
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2005 à 15:47:23  profilanswer
 

Personne veut suivre ma requête :spamafote:

n°1160447
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2005 à 15:48:20  profilanswer
 

C'est mal de tronquer une table de logs.

n°1160456
RaTo
Posté le 26-07-2005 à 15:54:48  profilanswer
 

Arjuna a écrit :

Personne veut suivre ma requête :spamafote:


 
J'ai créé les index et balancé ta requête, ça tourne là, ça à l'air de ramer tout autant...
 
Je crois que le problème c'est en fait les 22 000 lignes.

n°1160459
skeye
Posté le 26-07-2005 à 15:55:50  profilanswer
 

RaTo a écrit :

J'ai créé les index et balancé ta requête, ça tourne là, ça à l'air de ramer tout autant...
 
Je crois que le problème c'est en fait les 22 000 lignes.


22000 c'est pas la mer à boire non plus...à moins que le serveur soit vraiment juste ya pas de raison que ce soit si lent!


---------------
Can't buy what I want because it's free -
n°1160464
RaTo
Posté le 26-07-2005 à 15:59:31  profilanswer
 

RaTo a écrit :

J'ai créé les index et balancé ta requête, ça tourne là, ça à l'air de ramer tout autant...

ça tourne toujours..


Message édité par RaTo le 26-07-2005 à 16:00:08
n°1160481
RaTo
Posté le 26-07-2005 à 16:06:50  profilanswer
 

Bon j'ai arrêté la requête d'Arjuna, ça ramait trop..

n°1160522
Beegee
Posté le 26-07-2005 à 16:42:38  profilanswer
 

Et mes requêtes alors ? :D

n°1160638
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2005 à 18:37:25  profilanswer
 

C'est étrange que ça ramme autant, t'as combien de login différents ?
 
Parcequ'un IN, c'est lent, certes, mais à la base, si le nombre est limité, ça doit quand même pas prendre des siècles... Idem pour un group by sur 22000 lignes, ça représente pas un gros volume.
 
Une requête normale fonctionne ?

n°1160703
RaTo
Posté le 26-07-2005 à 19:52:10  profilanswer
 

Bonsoir les amis,
 
Je vous réponds juste, je continuerai à tester demain au boulot, là je ne peux pas, merci de votre aide.

n°1161096
RaTo
Posté le 27-07-2005 à 09:36:32  profilanswer
 

Arjuna a écrit :

C'est étrange que ça ramme autant, t'as combien de login différents ?


582.

Arjuna a écrit :


Une requête normale fonctionne ?


Oui.

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [résolu] Problème de requête, CPU à 100%...

 

Sujets relatifs
[VB][RESOLU]Probleme lors d'un demarrage d'un prg fait en vbProbleme de modification dans un fichier!
[Résolu] Prob avec suppression maintenant :P[Résolu] Importer sous Access
[Resolu]macro suite a une saisie clavier[RESOLU] [MySQL API C] Problème avec mysql_query
[SQL] Problème écriture requête 
Plus de sujets relatifs à : [résolu] Problème de requête, CPU à 100%...


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR