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 :

Indexation de base de données


Sujet :

Développement SQL Server

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France, Ain (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2009
    Messages : 22
    Par défaut Indexation de base de données
    Bonjour,

    Je ne comprends pas pourquoi mon code ne marche pas

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
        DECLARE @TableName NVARCHAR(128), @IndexName NVARCHAR(128), @SQL NVARCHAR(MAX)
     
        DECLARE IndexCursor CURSOR FOR
        SELECT OBJECT_NAME(IPS.object_id) AS TableName, I.name AS IndexName, IPS.index_id, IPS.avg_fragmentation_in_percent
        FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') IPS
        JOIN sys.indexes I ON IPS.object_id = I.object_id AND IPS.index_id = I.index_id
        WHERE I.type_desc <> 'HEAP' AND avg_fragmentation_in_percent > 10
        ORDER BY avg_fragmentation_in_percent DESC;
     
        OPEN IndexCursor
        FETCH NEXT FROM IndexCursor INTO @TableName, @IndexName, @SQL,
     
        WHILE @@FETCH_STATUS = 0
        BEGIN
            SET @SQL = CASE 
                WHEN avg_fragmentation_in_percent > 30 THEN 'ALTER INDEX [' + @IndexName + '] ON [' + @TableName + '] REBUILD;'
                ELSE 'ALTER INDEX [' + @IndexName + '] ON [' + @TableName + '] REORGANIZE;'
            END
            PRINT @SQL
            EXEC sp_executesql @SQL
            FETCH NEXT FROM IndexCursor INTO @TableName, @IndexName, @SQL
        END
     
        CLOSE IndexCursor
        DEALLOCATE IndexCursor
    Pouvez-vous m'aider ?

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 132
    Par défaut
    Bonjour,

    Citation Envoyé par Mont73 Voir le message
    mon code ne marche pas
    Qu'entends-tu par là ?
    Où rencontres-tu un problème ?

    • Une erreur d'exécution ?
      Quel est le message associé ?
    • Un résultat erroné ?
      Quel est le résultat obtenu ? Le résultat attendu ?
      En quoi le résultat obtenu ne correspond-il pas à tes attentes ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France, Ain (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2009
    Messages : 22
    Par défaut
    Il me dit que le champ testé dans case when n’existe pas alors qu'il est dans ma requête.

    J'attent du script qu'il reconstruise mes indexes ou qu'il les reorganise suivant le pourcentage de fragment

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 984
    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 984
    Billets dans le blog
    6
    Par défaut
    Il manque la variable pour recueillir cette information... C'est là votre erreur !
    De plus vous ne mettez pas le schéma SQL en préfixe de la table.... Cela partira en erreur si un index de table système est visé par votre script, car les tables systèmes sont dans le schéma "sys".

    Aussi il est préférable de faire des jointures plutôt que d'appeler des fonctions comme OBJECT_NAME
    ensuite il est préférable d'ouvrir un curseur avec les options suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LOCAL FORWARD_ONLY STATIC READ_ONLY
    Enfin vous n'utilisez pas la colonne index_id. Elle est donc inutile dans votre SELECT.
    Conseil :
    • utilisez "sysname" qui est le domaine réservé pour les identifiants SQL à la place de NVARCHAR(128)...
    • terminez vos instructions par le point-virgule ";"
    • utilisez QUOTENAME pour éviter les effets de bord des identifiants qui ne respecte pas la norme SQL
    • faite précer vos chaines de caractères de la lettre "N" majuscule pour le type NCHAR/NVARCHAR
    • utilisez directement EXEC("ma requête string") plutôt que la procédure sp_executesql pour des requêtes aussi simples...



    Script rectifié :

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    DECLARE @TableName sysname, 
            @TABLE_SCHEMA sysname,
            @IndexName sysname, 
            @FRAGMENTATION FLOAT,
            @SQL NVARCHAR(MAX);
     
    DECLARE IndexCursor CURSOR 
       LOCAL FORWARD_ONLY STATIC READ_ONLY
       FOR   SELECT o.name AS TableName, 
                    s.name AS TableSchema,
                    i.name AS IndexName, 
                    IPS.avg_fragmentation_in_percent
             FROM   sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS IPS
                    JOIN sys.indexes AS i ON IPS.object_id = i.object_id AND IPS.index_id = i.index_id
                    JOIN sys.objects AS o ON IPS.object_id = o.object_id
                    JOIN sys.schemas AS s ON o.schema_id = s.schema_id
             WHERE  i.type_desc <> 'HEAP' AND avg_fragmentation_in_percent > 10
             ORDER  BY avg_fragmentation_in_percent DESC;
     
    OPEN IndexCursor;
     
    FETCH NEXT FROM IndexCursor 
       INTO @TableName, @TABLE_SCHEMA, @IndexName, @FRAGMENTATION;
     
    WHILE @@FETCH_STATUS = 0
    BEGIN
     
       SET @SQL = N'ALTER INDEX ' + QUOTENAME(@IndexName) 
                + N' ON ' + QUOTENAME (@TABLE_SCHEMA) + N'.' + QUOTENAME(@TableName) 
                + CASE 
                     WHEN @FRAGMENTATION > 30 
                        THEN N' REBUILD;'
                     ELSE N' REORGANIZE;'
                  END;
     
        PRINT @SQL;
     
        EXEC (@SQL);
     
        FETCH NEXT FROM IndexCursor 
           INTO @TableName, @TABLE_SCHEMA, @IndexName, @FRAGMENTATION;
    END
     
    CLOSE IndexCursor;
     
    DEALLOCATE IndexCursor;
    Enfin il n'est pas souhaitable de défragmenter de très petits index (moins de 64 pages par exemple) et il est en revanche intéressant de reconstruire les tables en HEAP...

    Dans ce cas :

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    DECLARE @TableName sysname, 
            @TABLE_SCHEMA sysname,
            @IndexName sysname, 
            @FRAGMENTATION FLOAT,
            @HEAP bit,
            @SQL NVARCHAR(MAX);
     
    DECLARE IndexCursor CURSOR 
       LOCAL FORWARD_ONLY STATIC READ_ONLY
       FOR   SELECT QUOTENAME(o.name) AS TableName, 
                    QUOTENAME(s.name) AS TableSchema,
                    QUOTENAME(i.name) AS IndexName, 
                    IPS.avg_fragmentation_in_percent,
                    CASE WHEN i.type_desc = 'HEAP' THEN 1 ELSE 0 END AS IS_HEAP
             FROM   sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS IPS
                    JOIN sys.indexes AS i ON IPS.object_id = i.object_id AND IPS.index_id = i.index_id
                    JOIN sys.objects AS o ON IPS.object_id = o.object_id
                    JOIN sys.schemas AS s ON o.schema_id = s.schema_id
             WHERE  avg_fragmentation_in_percent > 10
                    AND page_count > 64
             ORDER  BY avg_fragmentation_in_percent DESC;
     
    OPEN IndexCursor;
     
    FETCH NEXT FROM IndexCursor 
       INTO @TableName, @TABLE_SCHEMA, @IndexName, @FRAGMENTATION, @HEAP;
     
    WHILE @@FETCH_STATUS = 0
    BEGIN
     
       SET @SQL = CASE
                     WHEN @HEAP = 1
                        THEN N'ALTER TABLE ' + @TABLE_SCHEMA + N'.' + @TableName + ' REBUILD;'
                     WHEN @FRAGMENTATION > 30 
                        THEN  N' REBUILD;'
                     ELSE N'ALTER INDEX ' + @IndexName 
                             + N' ON ' + @TABLE_SCHEMA + N'.' + @TableName + N' REORGANIZE;'
                  END;
     
        PRINT @SQL;
     
        EXEC (@SQL);
     
        FETCH NEXT FROM IndexCursor 
           INTO @TableName, @TABLE_SCHEMA, @IndexName, @FRAGMENTATION, @HEAP;
     
    END
     
    CLOSE IndexCursor;
     
    DEALLOCATE IndexCursor;
    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/ * * * * *

Discussions similaires

  1. Réponses: 4
    Dernier message: 16/12/2004, 13h56
  2. base de donné sans avoir un serveur!!
    Par Sawbo dans le forum Bases de données
    Réponses: 7
    Dernier message: 30/07/2004, 09h08
  3. probleme construction base de donnes MySql...Help
    Par chakan dans le forum Requêtes
    Réponses: 7
    Dernier message: 21/07/2004, 11h27
  4. [Tomcat][Oracle] connexion base de donnes debutant....
    Par yogz dans le forum Tomcat et TomEE
    Réponses: 8
    Dernier message: 16/07/2004, 13h32
  5. connexion base de donné
    Par saidi dans le forum MFC
    Réponses: 3
    Dernier message: 07/08/2002, 22h22

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