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 :

Pourquoi SQL server n'utilise pas le bon index


Sujet :

MS SQL Server

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    616
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mars 2007
    Messages : 616
    Points : 556
    Points
    556
    Par défaut Pourquoi SQL server n'utilise pas le bon index
    Bonjour,

    j'aimerais savoir pourquoi SQL Server n'utilise pas l'index sur la colonne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select *
    from fact_prm
    where prm_d_crt > '20070101'
    J'ai un index sur la colonne prm_d_crt mais je ne sais pour quelle raison lorsque je demande d'afficher le plan d'execution il affiche le Clustered Index Scan

    alors que la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select *
    from fact_prm
    where prm_d_crt = '20070101'
    utilise bien l'index sur la colonne prm_d_crt.

    voici le script de création d'index
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    /****** Object:  Index [IX_D_CREA]    Script Date: 02/13/2009 16:26:35 ******/
    CREATE NONCLUSTERED INDEX [IX_D_CREA] ON [dbo].[FACT_PRM] 
    (
    	[PRM_D_CRT] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Une des premières raison est parce que vous utilisez SELECT *.
    Même si vous avez besoin de toutes les colonnes, n'utilisez jamais SELECT *.

    Ensuite combien de lignes compte votre table, et parmi celles-ci combien correspondent au critère de la clause WHERE ?
    Si beaucoup de lignes répondent à cette clause, alors le moteur va préférer parcourir toute la table que de chercher dans l'index, s'il estime que cela est plus rapide / moins gourmand en ressources.

    Enfin votre index n'est pas couvrant, c'est-à-dire que les colonnes impliquées dans votre requête ne sont pas la clé de l'index.
    Je ne peux pas vous guider parce que vous avez utilisé un SELECT *.

    Si vous êtes en 2005, n'oubliez pas la clause INCLUDE de l'ordre CREATE INDEX

    @++

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 917
    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 : 21 917
    Points : 51 693
    Points
    51 693
    Billets dans le blog
    6
    Par défaut
    Pour savoir si SQL Server à raison de ne pas utiliser cet index il suffit de lui faire exécuter la requête en lui forçant à utiliser cet index puis naturellement et en regardant le nombre d'IO effectué dans chaque cas.
    Ce n'est pas parce que vous mettez un index que ce sera automatiquement choisit. Avant d'exécuter, SQL Server analyse toutes les combinaisons, les évalues et choisit la meilleure.

    En supposante que votre index s'apelle X_FAC_PRM

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    -- affichage des stats de lectures
    SET STATISTICS IO ON;
    GO
    -- forçage de l'index
    SELECT *
    FROM fact_prm WITH( INDEX (X_FAC_PRM))
    WHERE prm_d_crt > '20070101';
    GO
    -- choix SQL
    SELECT *
    FROM fact_prm
    WHERE prm_d_crt > '20070101';
    GO
    Regardez dans l'onglet des messages et concluez par vous même !

    A +

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    616
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mars 2007
    Messages : 616
    Points : 556
    Points
    556
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Bonjour,

    Une des premières raison est parce que vous utilisez SELECT *.
    Même si vous avez besoin de toutes les colonnes, n'utilisez jamais SELECT *.

    Ensuite combien de lignes compte votre table, et parmi celles-ci combien correspondent au critère de la clause WHERE ?
    Ma table a 54 colonnes, dans la clause where il y a 1 seule colonne. Ce qui me semblait logique c'est qu'en faisant un critère sur la date de création "prm_d_crt" > 2007 ça élimine un bon nombre de résultats.

    Ma table possède 2340467 lignes. Ma requête me retourne 500000 lignes environs. Donc pourquoi parcourir tous les 2 millions de records quant on peut en éliminer les 3/4?
    Enfin votre index n'est pas couvrant, c'est-à-dire que les colonnes impliquées dans votre requête ne sont pas la clé de l'index.
    Je ne peux pas vous guider parce que vous avez utilisé un SELECT *.
    Alors pourquoi lorsque je demande WHERE d_crt = '20070101' SQL server passe bien par cet index?
    Pour savoir si SQL Server à raison de ne pas utiliser cet index il suffit de lui faire exécuter la requête en lui forçant à utiliser cet index puis naturellement et en regardant le nombre d'IO effectué dans chaque cas.
    Ce n'est pas parce que vous mettez un index que ce sera automatiquement choisit. Avant d'exécuter, SQL Server analyse toutes les combinaisons, les évalues et choisit la meilleure.
    Je l'ai fait voilà ce que ce me retourne, mais ça veut dire quoi?



    (522639 row(s) affected)
    Table 'FACT_PRM'. Scan count 1, logical reads 2126274, physical reads 10908, read-ahead reads 1920, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

    (522639 row(s) affected)
    Table 'FACT_PRM'. Scan count 1, logical reads 107961, physical reads 4, read-ahead reads 107959, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Discussions similaires

  1. [MySQL] requete sql qui ne donne pas le bon array
    Par easyjava dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 02/11/2006, 14h41
  2. [SQL SERVER 2005] Utilisation de Exec dans une fonction ?
    Par Dadou74 dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 22/09/2006, 22h09
  3. sql server ne demarre pas
    Par popialex dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 24/07/2006, 12h48
  4. Sql Server Probleme Truncate / Pas Arrondi
    Par Nathan_2 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 02/05/2006, 19h09
  5. Réponses: 3
    Dernier message: 05/04/2006, 15h40

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