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

MS SQL Server Discussion :

Utiliser un index avec des valeurs partielles


Sujet :

MS SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut Utiliser un index avec des valeurs partielles
    Supposons une table qui contienne un champ NAME et un index sur ce champ.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE INDEX my_index ON my_table (NAME)
    Une requête comme celle qui suit va utiliser l'index:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM my_table WHERE NAME="Alexandre"
    Maintenant j'aimerais faire des requêtes sur valeurs partielles (des préfixes pour être précis) mais je souhaite que l'index soit aussi utilisé, comme ceci par exemple,:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM my_table WHERE NAME="Alex%"
    En retour j'obtiendrais tous les Alex, Alexandre, Alexandra, etc.

    Techniquement parlant, rien ne l'empêche. En C il suffirait d'utiliser la fonction strncmp() au lieu de strcmp() pour faire des comparaisons (et donc des recherches) sur valeur partielle.

    Est-ce possible de forcer SQL d'en faire autant ?
    Merci.

  2. #2
    Expert confirmé
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Par défaut
    Pas de besoin de forcer SQL en réalité.
    L'optimiseur pourra utiliser l'index dans ce cas (mais dans votre requête il faut utiliser l'opération LIKE) :

    Exemple

    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
    CREATE TABLE name
    (
     nom varchar(50)
    )
     
    INSERT name VALUES ('TOTO')
    GO 100000
     
    INSERT name VALUES ('alex')
    INSERT name VALUES ('alexandre')
    INSERT name VALUES ('alexandra')
     
    CREATE CLUSTERED INDEX PK_name
    ON dbo.name ( nom )
     
    SELECT * FROM name WHERE nom LIKE 'alex%'
    ++

  3. #3
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    C'est bon à savoir que même avec LIKE les index peuvent être utilisés !
    D'habitude je vérifie mes requêtes avec le "execution plan" (Ctrl-M dans le menu "Query", désolé j'ai des softs en anglais). Est-ce suffisant pour vérifier dans ce cas ?

    Merci !

  4. #4
    Expert confirmé
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Par défaut
    Vous pouvez le vérifier avec le plan d'exécution réel également ou encore en utilisant les options SET STATISTICS IO pour voir le nombre de pages lues pour votre recherche ou scan d'index selon le cas

    ++

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    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 010
    Billets dans le blog
    6
    Par défaut
    ATTENTION : votre jeu d'essais n'étant pas consistant il est probable que votre index ne soit pas utilisé et qu'il en résulte un SCAN de table !

    En effet, pour faire des essais d'utilisation d'index il faut un volume de données et une distribution des données proche de la réalité, c'est à dire au moins quelques dizaines de milliers de lignes au minimum !

    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/ * * * * *

  6. #6
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    OK m3rci mikedaven

    J'ai d'autres questions à propos d'index qui sont un peu en marge du sujet initial, mais je les pose ici afin d'éviter d'ouvrir un nouveau sujet.

    Quelle différence entre une "table" et un "index" du point de vue de l'écriture sur disque ?
    En fait je voudrais constater qu'il n'y en a pratiquement aucune. Exemple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE my_table
    (
     id INT,
     name VARCHAR(50)
    )
     
    CREATE CLUSTERED INDEX idx1_id ON my_table (id)
     
    CREATE NON CLUSTERED INDEX idx2_name ON my_table (name) INCLUDE (id)
    Si j'ai bien compris, il y a 2 B+tree qui seront créés sur disque et qui contiendront les mêmes données à peu de choses près. Toutes les paires (id, name) seront stockées en double, une fois ordonnées selon 'id' et l'autre selon 'name'. A partir du moment où un index est aussi stocké comme une table, pourquoi ne pourrions nous pas faire une requête de ce genre afin de voir le contenu d'un index ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from idx2_name

  7. #7
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    SQLpro,
    Je ne donnais qu'un exemple pour illustrer mes propos sur le forum.

    Mais je n'ai pas compris ton intervention. Les index ne sont utilisés que s'il y de gros volumes de données, sinon jamais ?

  8. #8
    Membre éprouvé

    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 448
    Par défaut
    Citation Envoyé par camboui Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE my_table
    (
     id INT,
     name VARCHAR(50)
    )
     
    CREATE CLUSTERED INDEX idx1_id ON my_table (id)
     
    CREATE NON CLUSTERED INDEX idx2_name ON my_table (name) INCLUDE (id)
    Normalement dans ce scénario, id serait une clé primaire.
    Comme ça ne l'est pas j'ai un léger doute mais je pense qu'il est inutile d'inclure (clause INCLUDE) id dans le second index.
    Car celui-ci serait d'office inclu (puisque c'est LUI qui permet de retrouver physiquement la ligne sur le disque).

    Concernant votre question, si vous n'employez (sélection et filtre) d'une table des colonnes qui appartiennent toutes à un index, sql server va lire uniquement l'index.
    Il est donc inutile (et encombrant) d'avoir une syntax SELECT ... FROM INDEX...

Discussions similaires

  1. utilisation de edit avec des valeurs numériques
    Par oliv27400 dans le forum Interfaces Graphiques
    Réponses: 7
    Dernier message: 21/06/2010, 18h06
  2. UNIQUE index avec des valeurs null
    Par DeeVoiD dans le forum MySQL
    Réponses: 2
    Dernier message: 24/03/2009, 16h18
  3. Problème de "select" avec des valeurs a null
    Par SchpatziBreizh dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 01/07/2005, 16h08
  4. Réponses: 1
    Dernier message: 06/08/2003, 11h48
  5. Réponses: 6
    Dernier message: 04/04/2003, 15h28

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