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

Administration SQL Server Discussion :

Identification relative VS performance


Sujet :

Administration SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut Identification relative VS performance
    Bonjour,

    Une petite question pour savoir que penser de l'identification relative d'un point de vue performance.

    Histoire d'être bien sur la même longueur d'onde, voici ce qu'est l'identification relative pour moi.

    Prenons un cas typique dont voici la règle de gestion :
    Une personne peut posséder plusieurs numéro de téléphone et un numéro de téléphone est posséder par une seule personne.

    Ce qui donnera comme MCD :
    PERSONNE-0,n----POSSEDER----(1,1)-TELEPHONE

    Au niveau des tables, il n'y a que les clefs primaire qui nous intéressent :
    - une table T_PERSONNE_PRS avec la colonne PRS_ID INT IDENTITY(1,1) comme clef primaire.
    - une table T_TELEPHONE_TEL avec les colonnes PRS_ID et TEL_ID comme clef primaire composée. Où la numérotation de TEL_ID recommence à 1 pour chaque valeur de PRS_ID.

    Ce que j'en ai compris :
    Au niveau des requêtes de sélection, cela sera plus performant car tous les numéros d'une même personne seront regroupé sur la même page de l'index cluster.
    Au niveau des insertions, cela va immanquablement être moins performant car il faudra, à chaque insertion, réorganiser l'index (sauf si on insère un nouveau numéro pour la personne avec l'id maximal).


    Du coup, que faut-il préférer ? Je ne suis pas assez versé dans l'administration et l'optimisation pour parvenir à juger de l'impact de ce genre de chose. C'est pourquoi je fais appel à vous.

    Merci d'avance.

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 002
    Billets dans le blog
    6
    Par défaut
    Toute clef primaire créé un index avec des statistiques derrières. Les statistiques ne sont disponibles que pour la première colonne d'un index composite. Dès lors que vous avez plusieurs colonnes dans un index l'optimisation est souvent moins bonne. C'est le cas avec cette problématique d'identification relative...
    De plus les PK créée des index CLUSTERED dont la valeur est utilisée comme repère de ligne dans tous les index secondaires (NON CLUSTERED). Avec deux colonnes composant la clef d'index, ce repère est donc 2 fois plus gros et impacte tous les index....

    Et comme vous l'avez remarqué, une clef primaire sémantique (donc index cluster) sera notablement plus fragmentée car :
    - l'ordre n'est pas constant à l'insertion (défaut de monotonie)
    - chaque update dans la clef impacte tous les index secondaires

    Une solution consiste donc à avoir en sus de la clef primaire de type IDENTITY une clef alternative sur PRS_ID + NUM tel, et c'est probablement cet index qui sera utilisé pour récupérer un n° de téléphone dans les jointures !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Merci beaucoup pour cet éclaircissement.

  4. #4
    Membre actif
    Homme Profil pro
    R&D
    Inscrit en
    Avril 2004
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : R&D

    Informations forums :
    Inscription : Avril 2004
    Messages : 127
    Par défaut
    Kropernic,
    Fais attention sur le point des index supplémentaires et les colonnes de données.
    Si ta table d'association n'a pas des index (ou le petit nombre des index) mais contient les colonnes, il n'est pas évident d'avoir une clé supplémentaire auto-incrément.
    Explication : dans ce cas t'a besoin d'un index composite supplémentaire sur les colonnes de références et toutes le requêtes qui font la sélection des colonnes hors cet index seront impactées en terme de perf (clustered key seek vs index seek + clustered key seek) ainsi que pour l'insertion (MAJ l'index supplémentaire).

  5. #5
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 218
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Quelques remarques en passant.


    Citation Envoyé par SQLpro Voir le message
    Toute clef primaire créé un index avec des statistiques derrières
    Jusqu'ici pas de problème.


    Citation Envoyé par SQLpro Voir le message
    Les statistiques ne sont disponibles que pour la première colonne d'un index composite.
    Il serait temps que SQL Server tienne des stats sur la clé complète, à l’instar par exemple de DB2 qui procède ainsi depuis toujours, c'est-à-dire près de 30 ans.

    Extrait du document IBM DATABASE 2, Release 1.0 Reference Summary SX23-3740-1 (1984) :


    La colonne FULLKEYCARD permettait déjà de connaître les stats utiles, à une époque à laquelle Kropernic se souciait plus de son pouce et de son canardque des index...


    Citation Envoyé par SQLpro Voir le message
    Dès lors que vous avez plusieurs colonnes dans un index l'optimisation est souvent moins bonne.
    Conséquence de ce qui précède, mais en l’occurrence, en quoi consiste très précisément l’optimisation ? Efficacité du regroupement des téléphones dans les pages de données ?


    Citation Envoyé par SQLpro Voir le message
    C'est le cas avec cette problématique d'identification relative.
    Peut-être, mais sous réserve d’avoir une explication claire de ce qu’on entend par optimisation. Pour le moment on est au niveau pifométrique.


    Citation Envoyé par SQLpro Voir le message
    De plus les PK créée des index CLUSTERED
    Je suppose que vous voulez dire que chaque clé primaire est dotée d’un index cluster. S’il en est ainsi, je dirais : sauf si on préfère qu’il en soit autrement. Exemple (qui ne sera pas mis en œuvre !) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CREATE TABLE TELEPHONE
    (
            PersonneId        INTEGER     NOT NULL
          , TelephoneId       TINYINT     NOT NULL
          , TelephoneNumero   VARCHAR(24) NOT NULL
        , CONSTRAINT TEL_PK PRIMARY KEY NONCLUSTERED (PersonneId, TelephoneId) 
        , CONSTRAINT TEL_PSN_PK FOREIGN KEY (PersonneId) REFERENCES PERSONNE ON DELETE CASCADE
    ) ; 
     
    ALTER INDEX TEL_PK ON TELEPHONE REBUILD WITH (PAD_INDEX = ON, FILLFACTOR = 80) ;
     
    CREATE CLUSTERED INDEX TEL_NO_X ON TELEPHONE (TelephoneNumero) 
           WITH (PAD_INDEX = ON, FILLFACTOR = 80) ;
    =>


    Citation Envoyé par SQLpro Voir le message
    Avec deux colonnes composant la clef d'index, ce repère est donc 2 fois plus gros et impacte tous les index
    Dans le cas de la table TELEPHONE il n’en est pas ainsi (comme le plus souvent dans le cas de l’identification relative). La colonne PersonneId mesure 4 octets et la colonne TelephoneId un seul octet (soit au plus 255 occurrences de téléphones par personne, ce qui dans le cas de Kropernic est plus que très largement suffisant). Si l’on n’utilise pas l’identification relative, l’identifiant TelephoneId devient absolu, mais son type est au moins celui de PersonneId, c'est-à-dire INTEGER dans l’exemple, ce qui représente 4 octets. Maintenant, je ne sache pas que 4 + 1 soit deux fois plus « gros » que 4.

    Cela dit, si l’index cluster avait une clé composite avec des colonnes de type CHARACTER(N) avec N = gros, je ne dis pas. Mais on n’est absolument pas dans ce genre de scénario, Kropernic est quelqu’un de sérieux...


    Citation Envoyé par SQLpro Voir le message
    l'ordre n'est pas constant à l'insertion (défaut de monotonie)
    Si les ajouts des téléphones d’une personne se font aléatoirement, au fil des jours, c’est vrai, qu’il s’agisse de l’index primaire en cas d'identification relative ou de l’index secondaire en l’absence d’identification relative. En tout cas, lors des consultations :

    En mode « Joe Transaction » (direct, léger), ça n’est pas un problème dans la mesure où l’on ne cherche pas à ramener tous les téléphones à chaque transaction. En mode « Jane Query » (direct, lourd) ou « Bill Batch », les performances pourraient être dégradées, mais heureusement, le DBA aura fait son travail de surveillance et déclenché en conséquence les réorganisations dans le but de prévenir la dégradation des performances. Par ailleurs, l’effet de monotonie ne se fait pas ressentir tant que le FILLFACTOR est choisi correctement (@Kropernic : j’espère que vous avez bien prévu ce paramétrage en ce qui concerne la table des gifts et les tables des stocks...)


    Citation Envoyé par SQLpro Voir le message
    chaque update dans la clef impacte tous les index secondaires
    Dans le cas de Kropernic (sauf s’il n’a pas suivi mes conseils), la valeur d’une clé primaire est invariante et dépourvue de toute signification, donc en l'occurrence aucun update en vue.


    Citation Envoyé par SQLpro Voir le message
    Une solution consiste donc à avoir en sus de la clef primaire de type IDENTITY une clef alternative sur PRS_ID + NUM tel, et c'est probablement cet index qui sera utilisé pour récupérer un n° de téléphone dans les jointures !
    Hum... Avec un seul index (utilisation de l’identification relative), les jointures se passent très bien, mais elles sont plus coûteuses avec votre index secondaire (voir les schémas en annexe ci-dessous). Si l’on vous suivait, on aurait désormais deux index sur les bras au lieu d’un seul, avec un surcoût important en I/O c'est-à-dire en accès aux disques tant en lecture qu’en écriture (je sais : tout est dans le cache, avec la nouvelle technologie de disques Tartempion on va dix fois plus vite, le temps de verrouillage est réduit d’autant, etc.) : pour ma part, je passe volontiers cet index supplémentaire au fil du rasoir d’Ockham et j’en resterai à l’identification relative.

    Cela dit, je ne généralise pas et ne prétends pas avoir raison à tout coup, l’expérience m’a appris à être prudent et ne pas me fier à ma seule intuition ou à mes habitudes : Vérité en deçà des Pyrénées, erreur au-delà... Mais il y a une chose dont je suis sûr : c’est sur la base d’un prototypage des performances sérieux que c’est telle solution qu’il faut retenir plutôt qu’une autre, résultats chiffrés en main pour une appréciation objective.

    En tout cas, vu les coûts I/O (cf. annexe ci-dessous), je ne m’engage pas trop en disant que Kropernic peut conserver sans problème l’identification relative :
    PERSONNE-0,n----POSSEDER----(1,1)--TELEPHONE
    En effet, pour accéder à une page de données, le nombre d’I/O est égal à H + 1, tandis que sans identification relative, le coût est égal à H’ + 1 + H’’ ; par ailleurs l’index primaire n’est pas obèse (les clés mesurent 5 octets, on a vu pire), la clé primaire n’est jamais modifiée, etc.

    Mais si un prototypage des performances montrait que malgré tout c’est l’autre solution qui était à retenir, au nom de l’indépendance physique (8e des 12 règles de Codd), c’est sous le capot que les transformations s’effectueraient, de façon transparente.


    Annexe. Coût I/O (accès aux disques)

    1) Avec utilisation de l’identification relative

    Suite à réorganisation de la table TELEPHONE, la situation est synthétisée dans la figure ci-dessous. Soit H la hauteur de l’arbre, c'est-à-dire le nombre de niveaux de l’index cluster (sans les données) : le coût pour accéder à un numéro de téléphone de la personne 12345 est égal au plus à H+1 I/O. Par exemple pour donner un ordre de grandeur — observé avec DB2 for z/OS, à ajuster évidemment dans le cas de SQL Server —, H = 2 pour moins de 85 000 téléphones, et H = 3 pour moins de 25 000 000. On peut voir venir.



    A supposer qu’une personne ait moins de 256 téléphones (du fait de l’utilisation du type Tinyint pour la colonne TelephoneId, cf. l’instruction CREATE TABLE ci-dessus), le coût d’une requête pour récupérer tous les téléphones d’une personne est égal au coût de la récupération d’un de ses téléphones en particulier (+ 1 I/O disons si les téléphones sont à cheval sur deux pages).


    2) Sans utilisation de l’identification relative

    La situation devient la suivante, dans laquelle on peut considérer que H’’ = H’ + 1, bien que la clé primaire mesure 4 octets cette fois-ci au lieu de 5 (par comparaison avec les chiffres précédents qui valent pour H, à peu de choses près (toujours avec DB2) H’ = 2 pour moins de 97 000 téléphones, et H’ = 3 pour moins de 30 000 000).


  6. #6
    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
    Belle réponse fsmel, comme d'habitude, mais n'y a-t-il pas une erreur dans la bataille car il me semble que la traduction du MCD vers le MPD est erronée :
    Citation Envoyé par Kropernic Voir le message
    Une personne peut posséder plusieurs numéros de téléphone et un numéro de téléphone est possédé par une seule personne.

    Ce qui donnera comme MCD :
    PERSONNE-0,n----POSSEDER----(1,1)-TELEPHONE

    Au niveau des tables, il n'y a que les clefs primaire qui nous intéressent :
    - une table T_PERSONNE_PRS avec la colonne PRS_ID INT IDENTITY(1,1) comme clef primaire.
    - une table T_TELEPHONE_TEL avec les colonnes PRS_ID et TEL_ID comme clef primaire composée. Où la numérotation de TEL_ID recommence à 1 pour chaque valeur de PRS_ID.
    Rien à dire sur la table T_PERSONNE_PRS, mais sur la table T_TELEPHONE_TEL j'aurai écrit :
    - une table T_TELEPHONE_TEL avec la colonne TEL_ID INT IDENTITY(1,1) comme clef primaire, et la colonne PRS_ID comme clef étrangère indexée référençant T_PERSONNE_PRS.PRS_ID.

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

Discussions similaires

  1. [WD10] Analyse : identification relative
    Par Medivh dans le forum WinDev
    Réponses: 4
    Dernier message: 16/11/2012, 13h37
  2. [MCD] MCD avec identification relative
    Par AiDuK dans le forum Schéma
    Réponses: 12
    Dernier message: 20/02/2010, 19h35
  3. [MCD] identification relative et entité faible
    Par erox44 dans le forum Schéma
    Réponses: 5
    Dernier message: 07/03/2008, 09h21
  4. [MCD] représentation d'une identification relative
    Par ZDAZZ dans le forum Schéma
    Réponses: 2
    Dernier message: 05/04/2007, 13h49
  5. [conception] problème identification relative
    Par mel02 dans le forum Modélisation
    Réponses: 4
    Dernier message: 19/01/2006, 17h00

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