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 Oracle Discussion :

Optimisation en utilisant les index


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 15
    Par défaut Optimisation en utilisant les index
    Bonjour,
    J'utilise les trois tables suivantes dans ma base de données Oracle 10G.

    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
    create table USER
    (
        USER_ID 		    NUMBER(10) not null,
        FIRST_NAME                 	    VARCHAR(50),
        LAST_NAME                 	    VARCHAR(50),
        primary key (USER_ID)
    );
     
     
     
    create table TASK
    (
        TASK_ID 		    NUMBER(10) not null,
        TASK_NAME                 	    VARCHAR(50),
        primary key (TASK_ID)
    );
     
     
     
     
    create table TASK_USER
    (
        USER_ID 		    NUMBER(10),
        TASK_ID 		    NUMBER(10),
        EXPIRY_DATE 	    DATE
    );
    Un utilisateur peut effectuer plusieurs taches. Une tache peut être réalisées par plusieurs utilisateurs. Je souhaite optimiser la requête qui renvoie les taches d'un utilisateur donné.

    Il y a actuellement un 1 million de lignes dans la table TASK, 100 mille ligne dans la table USER, et 1,2 million de ligne dans la table TASK_USER.
    Lorsqu'un utilisateur n'est plus affecté à une tache donnée, au lieu de supprimer physiquement la ligne, je remplis une date de suppression, d'où la colonne EXPIRY_DATE.




    Ma requête est la suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select TASK_ID, TASK_NAME from TASK_USER, TASK where TASK_USER.USER_ID = ? and TASK_USER.EXPIRY_DATE is null and TASK_USER.TASK_ID = TASK.TASK_ID;
    Quels index dois-je créer pour optimiser ma requête ?

    Merci pour votre aide

  2. #2
    Membre chevronné
    Avatar de argoet
    Inscrit en
    Mai 2002
    Messages
    582
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 582
    Par défaut
    Compte tenu du nombre d'enregistrements de vos différentes tables , je ne croit pas que vous aillez besoin de rajouter des index , vos clefs primaires devrait etre sufisantes .

    Les statistiques Oracle sont elles effectives sur vos tables ?

    Quelle sont vos temps de réponses sur votre requete des taches d'un utilisateurs ?

    Au besoin , vous pouvez essayer de voir ce que donne ce qui suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    select /*+ RULE */ 
           T.TASK_ID, T.TASK_NAME
    from   TASK T ,  TASK_USER U   
    where  U.USER_ID = &1
    And    U.task_id > 0
    And    U.EXPIRY_DATE is null        
    And    T.TASK_ID = U.TASK_ID;

  3. #3
    Membre éprouvé
    Inscrit en
    Septembre 2008
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 101
    Par défaut
    Tu fais ta recherche sur 1 user particulier ou tu veux la liste de toutes les tâches pour tous les users ?

  4. #4
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 15
    Par défaut
    Désolé, il y avait une erreur dans mon premier message que je viens de modifier. Il n'y a pas de clef primaire sur la table TASK_USER
    La raison est que quand je ne connais pas l'utilisateur précisément, j'ai un utilisateur par défaut à qui j'affecte la tache. je peux donc avoir deux fois le même couple (USER_ID, TASK_ID) dans la table TASK_USER.

    Sur la table TASK_USER, j'ai créé un index sur USER_ID et un deuxième index sur TASK_ID.

    Avec ça, j'ai un temps de réponse de quelques secondes par requête pour un utilisateur donné (pour répondre à la question de spdev666). Etant donné que j'utilise souvent cette requête dans mon logiciel, je dois encore optimiser la requête.

    Merci pour votre aide.

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Citation Envoyé par jelefevre2003 Voir le message
    La raison est que quand je ne connais pas l'utilisateur précisément, j'ai un utilisateur par défaut à qui j'affecte la tache. je peux donc avoir deux fois le même couple (USER_ID, TASK_ID) dans la table TASK_USER.
    Est-ce que cette information de tâche sans user est exploitable ?
    Si elle ne présente pas d'intérêt ne l'enregistrez pas et gardez votre PK.

    La cohérence du modèle est la plus importante.

    Que se passe-t'il si le même utilisateur effectue deux fois la même tâche ?

  6. #6
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    En fait, votre requête cherche des informations dans la table TASK: TASK_ID, TASK_NAME mais les critères de sélection concernent la table TASK_USER: USER_ID et EXPIRY_DATE. Donc vous pouvez reformuler votre requête comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Select t.task_id, t.task_name
      From TASK t
     Where task_id In (Select task_id 
    			from TASK_USER
    			where user_id = ?
                                       And expiry_date Is Null
    		        )
    Vu la volumétrie des tables et en supposant des distributions uniformes, le critère user_id devrait être assez sélectif. Pour cette requête votre meilleur index pour la table TASK_USER est un index composite sur les zones (USER_ID, TASK_ID) et le plan d'exécution devrait l'utiliser avec un RANGE_SCAN sans attaquer la table TASK_USER. Pour la table TASK vous avez déjà votre index du à la contraint clé primaire.
    Si les données sont reparti d'une manière uniforme la requête devrait s'exécuter assez rapidement pourvu que les statistiques sont à jour. Par contre ce type d'index est moins intéressant si vous cherchez les utilisateurs affectés à une tache précise. Donc, vous devez analyser l'ensemble des requêtes à exécuter pour décider de la meilleur façon d'indexer.
    Si votre table TASK_USER est plutôt une table d'historique: la plupart des enregistrements contient une date pour la zone expiry_date et il y a peu d'enregistrements avec une date nulle vous pouvez envisager peut être «*d'indexer les nuls*» pour cette date.
    Votre petit astuce concernant l'utilisateur bidon peut induire une non uniformité dans la distribution des données de la table TASK_USER ce qui pourrait impliquer la nécessité de collecter des histogrammes pour que l'optimiseur peut y prendre connaissance (je rejoint Waldar pour sa recommandation).
    En fin, il semble que vous devez en fait optimiser un traitement et non pas seulement une requête. Si une requête prendre 0,01 secondes pour s'exécuter mais vous l'exécutez 10000 fois dans votre traitement le temps total de votre traitement restera quand même de l'ordre de 100 secondes.

  7. #7
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 15
    Par défaut
    Je vais essayer de gérer différemment la notion d'utilisateur par défaut pour remettre la clef primaire (USER_ID, TASK_ID). J'ai fait qulques tests et c'est effectivement mon meilleur index sur cette table.
    Merci pour vos réponses.

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

Discussions similaires

  1. Optimisation en utilisant les algorithmes génétiques
    Par nourette dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 30/03/2010, 12h18
  2. [phpToPDF] Liens erronés si on utilise les indexes
    Par Dev_tun dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 06/03/2009, 12h11
  3. Utiliser les index de listes déroulantes dans un bloc séparé ?
    Par debie1108 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 03/05/2007, 08h43
  4. Optimisations mysql sur les requêtes SELECT: index
    Par leo'z dans le forum Débuter
    Réponses: 2
    Dernier message: 29/11/2003, 13h23

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