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

Développement SQL Server Discussion :

SQL Server 2005 et utilisation des indexes ou autres


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut SQL Server 2005 et utilisation des indexes ou autres
    Bonjour,

    J'en appelle à vos lumières parce que j'ai un comportement étrange. J'ai une table qui a plus de millions de lignes, on va dire que c'est la table tab(id, desc) avec un index sur la colonne ID.

    Je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Max(entryid) FROM Tab
    J'ai un retour instantané de la requête.

    Je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Max(entryid) FROM Tab WHERE desc like '%title%'
    Avec %title% qui existe, j'ai un retour instantané de la requête.

    Je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Max(entryid) FROM Tab WHERE desc like '%xxx%'
    Avec %xxx% qui n'existe pas, la requête prend 1000 ans (plus ou moins 1000 ans )

    Les plans d'exécution sont sensiblement les mêmes avec juste un usage à 100% de l'index dans le premier cas et 0% sur le filtre et 3 ou 6% sur le filtre selon que j'exécute la 2eme ou 3eme colonne.

    Déjà là, ça m'interpelle. Maintenant, les dévs qui m'ont signalé le problème me disent que dans leur cas ça prend toujours très longtemps. Pourquoi ? Simplement parce que leur requête ressemble à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Max(entryid) FROM Tab WHERE desc like '%' + @variable + '%'
    donc même si la variable est title ou une autre valeur qui fonctionne parfaitement si on la saisit en dur, en .Net ça prend très longtemps.

    N'y connaissant rien aux arcanes de SQL Server et encore moins de celles de .Net, j'en appelle donc à votre aide pour m'expliquer ce comportement étrange. A savoir qu'on a des solutions de contournement mais qu'on aimerait bien connaitre le fin mot de l'histoire

    Merci d'avance

  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 : 44
    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
    Par défaut
    Bonjour,

    Les statistiques de chaîne sous SQL Server sont collectées sur les 40 premiers et 40 derniers caractères de celles-ci.
    Donc si vos chaînes contiennent majoritairement plus de 80 caractères (ce dont à priori je doute dans votre cas), SQL Server n'a pas le moyen d'estimer combien de lignes il va devoir retourner, et choisit donc une manière sûre mais très lente de trouver les lignes : le scan de table ou d'index cluster.
    Est-ce que le plan de requête vous donne un index scan ou seek, et dans quels cas ? (vérifiez avec le plan d'exécution actuel, et non pas avec l'estimé)

    Dans votre première requête avec le WHERE, SQL Server doit avoir, dans ses statistiques (jetez-y un œil sous la node statistiques de la table, dans l'explorateur d'objets (F7)), un nombre de lignes estimé pour une telle valeur.
    Pour trouver la statistique en question, vous pouvez vous aider des vues système sys.tables, sys.columns, sys.stats et sys.stat_columns que vous devrez lier dans la même requête.

    A priori je dirai que ce n'est pas le cas pour votre seconde requête avec le WHERE, mais seules les statistiques peuvent le dire.

    Voyez donc si un UPDATE STATISTICS maTable maStatistique n'aide pas, et si c'est le cas poursuivez avec un UPDATE STATISTICS maTable maStatistique WITH FULLSCAN.

    Donnez-nous vos observations

    @++

  3. #3
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Dans les 2 premières requêtes j'ai un index scan sur la PK (probablement qu'il sait que la description retourne quasiment toutes les lignes et se contente donc de chercher le max de l'id dans l'index).

    Ce que je ne comprends pas c'est pourquoi, alors qu'il n'y a pas d'index sur la colonne DESC qui filtre les résultats, la requête est instantanée si je recherche une chaine de caractères qui est bien dans la colonne et très longue dans le cas contraire sachant que les plans d'exécution si rigoureusement identiques

    Pour info, 5% des lignes contiennent un DESC de plus de 80 caractères

  4. #4
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    J'ai trouvé, c'est bêtement à cause du cache

    Donc la question maintenant c'est : y a-t-il des règles particulières en .Net pour que les variables soient interprétées suffisamment tôt pour que le cache puisse être utilisé ? En effet (malheureusement j'ai pas le code ), en .Net la requête est très longue même avec une chaine recherchée qui est dans le cache (retour immédiat dans SQL Studio).

Discussions similaires

  1. [SQL Server 2005 [Express]] récupérer des données
    Par le_ben dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 30/08/2007, 17h11
  2. [SQL Server 2005] DELETE sur des doublons
    Par Shakta dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 16/05/2007, 11h13
  3. [Sql server 2005] Comment faire des taches planifiées?
    Par critok dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 31/05/2006, 12h19
  4. [SQL server 2005 express] liste des erreurs SQL serveur 2005
    Par critok dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 02/05/2006, 19h17
  5. [SQL Server 2005] Tables système et indexes
    Par Tips dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 04/04/2006, 09h01

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