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 :

Sélection de données à partir d'une arborescence massive


Sujet :

SQL Oracle

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 71
    Points : 89
    Points
    89
    Par défaut Sélection de données à partir d'une arborescence massive
    Bonjour,

    J'ai un souci de design. Je vous expose le problème ainsi que les différentes solutions envisagées.

    Le problème
    Je possède une arborescence (table ARBO) d'environ 1 millions d'éléments. L'utilisateur peut sélectionner 0,1 ou plusieurs éléments dans cette arborescence (noeuds ou feuilles).

    Plus tard, il peut extraire des données (contenues dans une table DATA).

    Il peut notamment extraire des données sur l'ensemble des feuilles des noeuds sélectionnés (donc potentiellement la moitié des éléments de l'arbre...)

    Solution 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * 
    FROM DATA 
    WHERE ID IN
    (SELECT ID_ELEMENT FROM ARBO START WITH ... CONNECT BY PRIOR ...)
    Cette solution fonctionne mais répond en 1 minute, ce qui est inacceptable.

    Solution 2
    Lorsque l'utilisateur a effectué sa sélection, conserver l'ensemble des feuilles de la sélection dans un CLOB et réexploiter ce CLOB plus tard sur la table DATA (SELECT * FROM WHERE ID IN "le CLOB") quand l'utilisateur demandera des données.

    En pratique, je ne sais pas trop comment rentrer proprement le résultat d'un SELECT dans CLOB et puis quelque chose me dit que cette solution est hideuse.

    Solution 3
    Utiliser une table temporaire, mais j'ai l'impression que je vais devoir créer une table temporaire par utilisateur (dynamiquement?).

    Avez-vous une solution plus élégante?

    Merci d'avance

  2. #2
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 460
    Points : 8 074
    Points
    8 074
    Par défaut
    Citation Envoyé par liouan Voir le message
    Utiliser une table temporaire, mais j'ai l'impression que je vais devoir créer une table temporaire par utilisateur (dynamiquement?)
    Je ne sais pas ce qui vous fait dire ça, mais il est peut-être utile de rappeler que :
    - une table temporaire peut être accédée par plusieurs utilisateurs (sous réserve que chacun ait les droits sur cette table)
    - dans une table temporaire, les données sont privées : chaque session ne peut voir que les données qu'elles a placées elle-même dans cette table. Autrement dit, quand on fait un "SELECT * FROM T", c'est comme s'il y avait un WHERE implicite qui filtre les données de la session.

    Je parle bien sûr des tables créées par la commande CREATE GLOBAL TEMPORARY TABLE ....
    Consultant / formateur Oracle indépendant
    Certifié OCP 12c, 11g, 10g ; sécurité 11g

    Ma dernière formation Oracle 19c publiée sur Linkedin : https://fr.linkedin.com/learning/oracle-19c-l-administration

  3. #3
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Plus tard, il peut extraire des données (contenues dans une table DATA).
    Le plus tard est problématique pour la version table temporaire si l'application est stateless (appli web), car l'utilisateur se reconnectera avec une nouvelle session. En statefull ça semble être une bonne approche simple à mettre en place.
    (donc potentiellement la moitié des éléments de l'arbre...)
    Comment est géré l'affichage des informations parce qu'afficher 500 000 lignes ça consomme des I/Os et du réseau et au final c'est plutôt inutilisable pour l'utilisateur, une pagination n'améliorerait elle pas les perfs ?
    conserver l'ensemble des feuilles de la sélection dans un CLOB
    Pourquoi dans un CLOB ? Si c'est la requête avec CONNECT BY qui est lente, déjà s'assurer qu'elle est correctement indexée, ensuite il est préférable de stocker l'information dans une table relationnelle de paramétrage (id_user, id_element, date_time...)

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 71
    Points : 89
    Points
    89
    Par défaut
    Je parle bien sûr des tables créées par la commande CREATE GLOBAL TEMPORARY TABLE ....
    J'ai en fait découvert ce type de tables en réfléchissant au problème, merci pour ces clarifications

    si l'application est stateless (appli web)
    Oui, c'est le cas. Appli web en Java/J2EE.

    Comment est géré l'affichage des informations parce qu'afficher 500 000 lignes[...]
    Pour ces informations, les données affichées ne pourront être que des données agrégées donc ça ne devrait pas poser de problèmes.

    il est préférable de stocker l'information dans une table relationnelle de paramétrage
    Je vais tenter cette solution.
    Il serait d'ailleurs pratique de partitionner cette table par id_user mais je n'ai que la version standard d'Oracle. j'ai donc 2 possibilités:
    • Indexer par id_user et voir si ça répond dans des temps corrects.
    • Créér une table "temporaire" pour chaque utilisateur, gérée manuellement (suppression de toutes les tables temporaires au démarrage de l'appli, création à l'ouverture de session et destruction à la fermeture de session (session HTTP)).

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 71
    Points : 89
    Points
    89
    Par défaut
    J'ai tenté la solution consistant à stocker le résultat de la sélection dans des tables intermédiaires.
    Le problème est que la sélection des éléments pour remplir la table prend 1 min.
    C'est une avancée car ça permet de ne faire ce calcul qu'une fois (alors que j'exploite le résultat plusieurs fois) mais ça reste globalement pénible pour l'utilisateur.

    Alors j'ai eu une autre idée en réorganisant la table ARBO.
    Avant, elle contenait une colonne ID (PK et donc indexée) et une colonne ID_PARENT
    Je l'ai recréée en 2 colonnes:
    une colonne ID (PK) et une colonne PATH, contenant le chemin de l'élément dans l'arborescence, stocké dans un VARCHAR2.

    Ainsi, la recherche de tous les feuilles d'un noeud se résume à une recherche par expression régulière sur le path. Et ça répond en < 0.1s

  6. #6
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Et la colonne id_parent était elle indexée ?

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 71
    Points : 89
    Points
    89
    Par défaut
    Et la colonne id_parent était elle indexée ?
    Oui, elle était indexée.

    Bizarrement, aujourd'hui, la requête avec 'CONNECT BY' ne prend plus 1 minute mais juste une poignée de secondes (même après un 'alter system flush buffer_cache'). Je parierais sur un changement de plan suite à une réévaluation des statistiques...

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 12/12/2006, 16h24
  2. [MySQL] Insérer des données à partir d'une db mysql dans un textarea
    Par minogttao dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 17/11/2006, 21h59
  3. Réponses: 10
    Dernier message: 17/11/2006, 15h20
  4. [MySQL] Enregistrer dans une base de données à partir d'une liste déroulante
    Par snakejl dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 17/05/2006, 16h32
  5. Mise à jour de données à partir d'une autre table
    Par rsc dans le forum Langage SQL
    Réponses: 7
    Dernier message: 05/04/2006, 10h53

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