Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 16/02/2011, 16h59   #1
Invité de passage
 
Inscription : septembre 2006
Messages : 9
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 9
Points : 3
Points : 3
Par défaut Optimisation d'une requete avec fonction Max

Bonjour,

Je ne suis pas un expert en SQL, et j'aimerai optimiser une requete car celle ci s'execute trop lentement et je viens vers vous car je pense qu'il est possible de mieux faire:

Code :
1
2
3
4
5
6
 
SELECT value,time FROM e_db
WHERE tag ='ABC' AND time= 
    (SELECT Max(time) 
    FROM e_db 
    WHERE  time <= '01/01/2010 00:00:00' AND tag='ABC')
En gros je cherche la valeur de l'enregistrement le plus récent mais antérieur à la date '01/01/2010 00:00:00'
Precision: il ne peut y avoir 2 enregistrement de value pour un tag à un time donnée.

La requete s'execute particulièrement lentement si aucun enregistrement n'a été fait avant la date donnée.

Merci,!!

JB

Tout coup de pouce et le bienvenu.
ghargamaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 17h09   #2
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
bonjour,

quel est votre sgbd + définition de la table + index déjà présent ?
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 17h12   #3
Membre Expert
 
Homme
Responsable de service informatique
Inscription : janvier 2009
Messages : 1 081
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Boutique - Magasin

Informations forums :
Inscription : janvier 2009
Messages : 1 081
Points : 1 875
Points : 1 875
Bonjour,
Je ne vois pas l'utilité de passer par une sous-requête...
Code SQL :
1
2
3
4
5
 
SELECT value,Max(time) 
FROM e_db 
WHERE  time <= '01/01/2010 00:00:00' AND tag='ABC'
GROUP BY value

Cette requête ne renvoie pas la même chose ?

Tatayo.
tatayo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 17h28   #4
Membre Expert
 
Avatar de Nudger
 
Homme Thomas Arnaud
Directeur de projet
Inscription : octobre 2010
Messages : 452
Détails du profil
Informations personnelles :
Nom : Homme Thomas Arnaud
Âge : 36
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Directeur de projet
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : octobre 2010
Messages : 452
Points : 1 012
Points : 1 012
Envoyer un message via Skype™ à Nudger
Bonsoir,

Citation:
Envoyé par tatayo Voir le message
Cette requête ne renvoie pas la même chose ?
Pas forcément:

1) Le GROUP BY dans cette requête provoque que chaque value distinctes sera renvoyé même si aucun time associée n'est égale au max considéré.
Alors que dans la requête de l'auteur du post, seules les value étant associées à un time = max(...) sont retournées.

2) De plus, une seule ligne sera retournée par value ce qui n'est pas forcément le cas de la requête de l'auteur.
__________________
www.nudge.org Surveillez et optimisez vos applications Java
Nudger est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 17h33   #5
Invité de passage
 
Inscription : septembre 2006
Messages : 9
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 9
Points : 3
Points : 3
Citation:
quel est votre sgbd + définition de la table + index déjà présent ?
Je crois que la BdD est SQL server. Je l'exploite via ODBC.
L'index j'en ai aucune idée

La table contient des enregistrements pour differents tag:

Un enregistrement= "Tag","Valeur","Date"

Citation:
Cette requête ne renvoie pas la même chose ?
tatayo, Nudger a repondu mieux que ce que je ne pourrai faire!
sauf concernant 2)
Ma requête ne renvoie q'une ligne car il ne peut y avoir plusieurs enregistrement à un time donné pour un tag donné.
ghargamaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 18h19   #6
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
bonjour

pour la rapidite, il faut penser a creer un index sur la date, mais descendant

a+
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2011, 01h48   #7
Expert Confirmé Sénior

 
Avatar de fsmrel
 
Spécialiste en bases de données
Inscription : septembre 2006
Messages : 2 882
Détails du profil
Informations professionnelles :
Activité : Spécialiste en bases de données
Secteur : Conseil

Informations forums :
Inscription : septembre 2006
Messages : 2 882
Points : 5 116
Points : 5 116
Citation:
Envoyé par dehorter olivier Voir le message
pour la rapidite, il faut penser a creer un index sur la date, mais descendant
Dans la série ceinture, bretelles et épingle à nourrisse, s'assurer que l'attribut Tag est lui aussi indexé, à moins bien sûr qu'un EXPLAIN PLAN (ou équivalent) montre que cela est inutile.
__________________
_
Faites simple, mais pas plus simple ! (A. Einstein)
E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

__________________

Bases de données relationnelles et normalisation : de la première à la sixième forme normale (Bonne lecture !)
fsmrel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2011, 09h35   #8
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
SQL serveur : regardez si le plan d'exécution de cette requête est mieux ou non :
Code :
1
2
3
4
5
6
7
8
9
10
 
WITH tmp AS 
(SELECT value, time, rank() over(ORDER BY time DESC) AS rnk
FROM e_db
WHERE tag = 'ABC' AND time <= '01/01/2010 00:00:00')
 
 
SELECT *
FROM tmp
WHERE rnk = 1
Concernant l'index, comme cité ci-dessus : tag, time desc.

Et si ca n'est toujours pas bon, vous pouvez créer un index comme ceci : tag, time desc, value
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2011, 09h34   #9
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 950
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 950
Points : 17 769
Points : 17 769
Céez cet index :
Code :
CREATE INDEX X_EDB_TAG_TIM ON e_db (tag, time) INCLUDE (value) WITH (FILLFACTOR = 80)
Et tout devrait aller 1000 fois plus vite !

Lisez l'article que j'ai écrit sur l'indexation : http://sqlpro.developpez.com/cours/quoi-indexer/

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2011, 10h37   #10
Invité de passage
 
Inscription : septembre 2006
Messages : 9
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 9
Points : 3
Points : 3
Re Bonjour,

Concernant la proposition de punkoff, c'est beaucoup plus long.

Concernant l'index je crois qu'il existe déjà sur time DESC.

La requete s'execute particulièrement lentement si aucun enregistrement n'a été fait avant la date donnée. Donc l'indexation n'apportera rien dans ce cas.

Donc merci pour votre aide, Je crois que je peux pas faire beaucoup mieux que ce que j'ai. De toute façon c'est déjà utilisable comme cela.

Salutations,

g
ghargamaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2011, 15h30   #11
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour,

Citation:
Envoyé par ghargamaster Voir le message
Concernant l'index je crois qu'il existe déjà sur time DESC.
Un index sur time n'est probablement pas sufffisant, et donc peut etre pas utilisé

Voyez l'index proposé par SQLPro :
Citation:
Envoyé par SQLpro Voir le message
Céez cet index :
Code :
CREATE INDEX X_EDB_TAG_TIM ON e_db (tag, time) INCLUDE (value) WITH (FILLFACTOR = 80)
il comprend la colonne tag et inclue la colonne value, afin que l'index soit couvrant.

D'ailleurs, je dirai même qu'il devrait être unique
Code sql :
1
2
 
CREATE UNIQUE INDEX X_EDB_TAG_TIM ON e_db (tag, time) INCLUDE (value) WITH (FILLFACTOR = 80)

Puisque vous dites :
Citation:
Envoyé par ghargamaster Voir le message
Precision: il ne peut y avoir 2 enregistrement de value pour un tag à un time donnée.

Citation:
La requete s'execute particulièrement lentement si aucun enregistrement n'a été fait avant la date donnée. Donc l'indexation n'apportera rien dans ce cas.
Au contraire, avec un bon index, la réponse devrait être d'autant plus rapide !(cela éviterait au SGBD de chercher quelque chose qui n'existe pas...)
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2011, 15h40   #12
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 993
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

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

Informations forums :
Inscription : août 2006
Messages : 10 993
Points : 18 246
Points : 18 246
Envoyer un message via MSN à CinePhil
Code :
AND time <= '01/01/2010 00:00:00'
Par contre comme il cherche un time inférieur à une date/heure donnée, je ne vois pas l'intérêt de classer les time en DESC ! Le SGBD devra parcourir tout l'index avant de s'apercevoir qu'il n'y a pas de ligne répondant à la demande. Par contre avec un index ASC, si la première date est par exemple '2010-07-24 23:00:00', pas besoin d'aller plus loin !

Au fait, le format de date standard en SQL est celui que j'ai donné, pas celui de la requête !

Et il ne faut pas nommer une colonne "time" qui est un mot réservé du langage SQL !
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/02/2011, 16h30   #13
Invité de passage
 
Inscription : septembre 2006
Messages : 9
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 9
Points : 3
Points : 3
si il faut que ce soit en time DESC, pour trouver rapidement le max(eventtime) quand il existe (ce qui est le plus courant)

Bon sinon, merci pour les conseils, je vais essayer de voir avec l'admin de la base s'il peut me créer cet index, car, moi je ne peux pas.
ghargamaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2011, 09h25   #14
Invité de passage
 
Inscription : septembre 2006
Messages : 9
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 9
Points : 3
Points : 3
Merci, l'indexation a bien améliorée le traitement (100x plus rapide montre en main)
ghargamaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h57.


 
 
 
 
Partenaires

Hébergement Web