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 :

Reindexation base...


Sujet :

MS SQL Server

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Reindexation base...
    * Bonjour, *

    comment réindexer une base SQL Server ?

    J'ai donc sélectionné les tables "Générer un Script SQL", j'ai donc décoché les cases dans "Mise en forme" dans options j'ai donc cocher "créer un script pour les index"

    j'ai donc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CREATE  UNIQUE  INDEX [ASSY_CODE_UK] ON [dbo].[ASSEMBLY]([ASSY_CODE], [ASSY_LIB_ID]) WITH  FILLFACTOR = 90 ON [PRIMARY]
    GO
    J'ai donc 278 tables donc 278 requétes.

    Le système est-il correct ??

    * Merci *

  2. #2
    Rédacteur/Modérateur

    Avatar de Fabien Celaia
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    4 224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2002
    Messages : 4 224
    Points : 19 567
    Points
    19 567
    Billets dans le blog
    25
    Par défaut
    Ben vous avez là que les indexes primaires... je doute que cela suffise ?

    Combien vous retourne la rquête suivante, jouée dans votre table ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select count(*) from sysindexes where indid >0 and indid <255
    De plus, il vous manque les ordres de suppression des l'indexes

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    fadace la requéte me retourne 1608

    Merci

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    si tu souhaite réindexe ta base ou une table tu peux utiliser:

    DBCC DBREINDEX [TableName], [IndexName], [Fill Factor]

    les 3 parametres sont facultatifs

  5. #5
    Rédacteur/Modérateur

    Avatar de Fabien Celaia
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    4 224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2002
    Messages : 4 224
    Points : 19 567
    Points
    19 567
    Billets dans le blog
    25
    Par défaut
    Non, le dbcc reindex n'a pas 3 paramètres facultatifs...

    Préférez le indexreorg qui est plus récent et minimise les verrous sur la table (permettant donc la réorganisation en ligne).

    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
    CREATE proc proc_reindex
    (@NomTable varchar(128) = NULL)
    as
    begin
    declare cur cursor for 
    select o.name, i.name 
    from sysindexes I INNER JOIN sysobjects O on O.id=I.id
    where i.indid < 255 and i.indid > 0
    and o.type='U'
    and o.name like coalesce(@NomTable, o.name)
     
    declare @tbl varchar(128), @indx varchar(128), @sql varchar(512)
     
    open cur
     
    FETCH  cur into @tbl, @indx
    WHILE @@FETCH_STATUS = 0
    BEGIN
       print 'Réindexation de la table '+ @tbl+', index '+@indx
       set @sql='dbcc indexdefrag(0,'+@tbl+','+@indx+')'
       exec (@sql)
       FETCH  cur into @tbl, @indx
    END
     
    close cur
    deallocate cur
    end
    ceci étant dit, le plan de maintenance vous offre une alternative.

  6. #6
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    344
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 344
    Points : 324
    Points
    324
    Par défaut
    J'ai cherché pendant longtemps une alternative à:
    DROP INDEX et CREATE INDEX
    pour réorganiser le plus correctement possible mes bases SQL server. J'avais finalement trouvé que la commande DBCC DBREINDEX était la mieux adaptée, et c'était celle qui se rapprochait le plus des DROP/CREATE. Maintenant, le soucis est que les tables sont lockées pendant l'opération. C'est cependant mieux que les DROP/CREATE où je mettait (pour plus de sécurité) la base en mode single user.
    Le désavantage d'un DBCC INDEXDEFRAG est qu'il va "skipper" les tables qui sont actuellement lockées", et ce n'est pas ce que je recherche. (en effet, les bases ne sont pas utilisées pendant la nuit donc je peux en profiter)
    Il me semble avoir lu quelque part que l'option proposée par les plans de maintenances serait plutôt un DBCC INDEXDEFRAG qu'un DBCC DBREINDEX .

    Voici une page où tout est bien expliqué (notemment les différences qui existent entre toutes les façons de réorganiser la base):

    http://www.sql-server-performance.com/rd_index_fragmentation.asp

  7. #7
    Rédacteur/Modérateur

    Avatar de Fabien Celaia
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    4 224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2002
    Messages : 4 224
    Points : 19 567
    Points
    19 567
    Billets dans le blog
    25
    Par défaut
    La même chose avec un dbcc reindex
    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
    CREATE proc proc_reindex2
    (@NomTable varchar(128) = NULL)
    as
    begin
    declare cur cursor for
    select o.name from sysobjects 
    where type='U'
    and name like coalesce(@NomTable, name)
     
    declare @tbl varchar(128), @sql varchar(512)
     
    open cur
     
    FETCH  cur into @tbl
    WHILE @@FETCH_STATUS = 0
    BEGIN
       print 'Réindexation de la table '+ @tbl
       set @sql='dbcc reindex('+@tbl+')'
       exec (@sql)
       FETCH  cur into @tbl
    END
     
    close cur
    deallocate cur
    end

  8. #8
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    344
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 344
    Points : 324
    Points
    324
    Par défaut
    Cool, génial fadace ton idée de le mettre en proc stockée ... Jusque là, moi je faisait comme ça:
    Je lance unn fichier reorg.bat qui contient les deux lignes suivantes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    osql -E -n -h -1 -i d:\maint_sql\reorg.sql -o d:\maint_sql\commande_reorg.sql
    osql -E -n -i d:\maint_sql\commande_reorg.sql -o d:\maint_sql\resultat_reorg.log
    avec le fichier reorg.sql:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    use NOM_BASE
    go
    SET NOCOUNT ON
    go
    select 'USE NOM_BASE'
    select 'GO'
    SELECT 'DBCC DBREINDEX([' + u.name + '.' + o.name + '], '''', 90)'
    FROM sysobjects o
    INNER JOIN sysusers u ON o.uid = u.uid
    WHERE o.name <> 'dtproperties' AND o.xtype = 'u'
    ORDER BY o.name
    go
    set nocount off
    go
    Je préfère personnelement quand tout reste "à l'intérieur de SQL server" donc je vais peut-être basculer mes jobs ...

  9. #9
    Rédacteur/Modérateur

    Avatar de Fabien Celaia
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    4 224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2002
    Messages : 4 224
    Points : 19 567
    Points
    19 567
    Billets dans le blog
    25
    Par défaut
    L'avantage de rester au T-SQL, c'est que c'est portable quel que soit l'os (ceci dit , avec MS-SQL, ça nous fait une belle jambe )

  10. #10
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 901
    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 901
    Points : 53 143
    Points
    53 143
    Billets dans le blog
    6
    Par défaut
    Allez, puisque vous êtes gentil je vous en balance une qui est pas piquée des vers...

    Elle réalise la defrag en tenant compte de la framentation et surtout et choisit de manière aléatoire les tables candidates à une defrag et elle s'arrête automatiquement à une certaine heure. elle a été conçue pour de gros serveurs...

    Si vous ne comprenez pas comment elle fonctionne, ni l'intérêt dites le moi.


    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    CREATE  PROCEDURE SP_DEFRAG_AUTO 
     
    /******************************************************************************
    * DEFRAGMENTATION AUTOMATIQUE DES INDEX PAR SEUIL EN ORDRE ALÉATOIRE          *
    *******************************************************************************
    * Copyright DATA SAPIENS - Frédéric Brouard - 11 février 2005                 *
    ******************************************************************************/
     
           @HEURE_LIMITE         VARCHAR(5) = '08:00', -- doit être de la forme '08:30' : heure limite de début de la dernière opération de défragmentation
           @RATIO_EXTENTSWITCHES FLOAT      = 1.3,     -- doit être d'au moins 1. Valeur inférieure à 1 ignorée. Valeur conseillée pour déclencher une défragementation : 1.3 à 2.0  Déclenche la défragmentation si ExtentSwitches / Extents >= @RATIO_EXTENTSWITCHES alors la défragmentation a lieu
           @RATIO_COUNT          FLOAT      = 1.3,     -- doit être d'au moins 1. Valeur inférieure à 1 ignorée. Valeur conseillée pour déclencher une défragementation : 1.3 à 2.0  Déclenche la défragmentation si BestCount / ActualCount  >= @RATIO_COUNT alors la défragmentation a lieu
           @RATIO_LOGICALFRAG    FLOAT      = 0.2      -- doit être d'au plus 1.  Valeur supérieure à 1 ignorée. Valeur conseillée pour déclencher une défragementation : 0.2 à 0.4. Déclenche la défragmentation si LogicalFrag / CountPages >= @RATIO_LOGICALFRAG
    AS
     
    DECLARE @TABLE_NAME VARCHAR (128)
    DECLARE @QUERY      VARCHAR (255)
    DECLARE @objectid   INT
    DECLARE @indexid    INT
    DECLARE @objectName VARCHAR(256)
    DECLARE @indexName  VARCHAR(256)
    DECLARE @GUID       uniqueidentifier
    DECLARE @T_BEFORE   FLOAT
    DECLARE @T_AFTER    FLOAT
    DECLARE @H          INT
    DECLARE @M          INT
    DECLARE @S          INT
    DECLARE @DATABASE   VARCHAR(128)
     
    SET NOCOUNT ON
     
    SET @DATABASE = DB_NAME(DB_ID())
     
    -- Curseur sur les tables d'exploitation à l'exclusion des tables systèmes et des vues
    DECLARE C_TABLES CURSOR 
    FOR
       SELECT TABLE_NAME
       FROM INFORMATION_SCHEMA.TABLES
       WHERE TABLE_TYPE = 'BASE TABLE'
         AND TABLE_NAME NOT IN (
    'sysusers',
    'systypes',
    'syssubscriptions',
    'sysreferences',
    'syspublications',
    'sysprotects',
    'syspermissions',
    'sysobjects',
    'sysmergesubsetfilters',
    'sysmergesubscriptions',
    'sysmergeschemachange',
    'sysmergepublications',
    'sysmergearticles',
    'sysmembers',
    'sysindexkeys',
    'sysindexes',
    'sysfulltextcatalogs',
    'sysforeignkeys',
    'sysfiles',
    'sysfilegroups',
    'sysdepends',
    'sysconstraints',
    'syscomments',
    'syscolumns',
    'sysarticleupdates',
    'sysarticles',
    'Mssubscriptions',
    'MSsubscription_properties',
    'MSsubscriber_schedule',
    'MSsubscriber_info',
    'MSsnapshot_history',
    'MSsnapshot_agents',
    'MSreplication_subscriptions',
    'MSreplication_objects',
    'MSrepl_version',
    'MSrepl_transactions',
    'MSrepl_originators',
    'MSrepl_errors',
    'MSrepl_commands',
    'Mspublisher_databases',
    'Mspublications',
    'MSpublication_access',
    'MSmerge_tombstone',
    'MSmerge_subscriptions',
    'MSmerge_replinfo',
    'MSmerge_history',
    'MSmerge_genhistory',
    'MSmerge_delete_conflicts',
    'MSmerge_contents',
    'MSmerge_agents',
    'MSlogreader_history',
    'MSlogreader_agents',
    'MSdistributor',
    'MSdistributiondbs',
    'MSdistribution_history',
    'MSdistribution_agents',
    'MSdistpublishers',
    'MSarticles',
    'MSagent_profiles',
    'MSagent_parameters'
    )  
     
     
    -- Creation de la table des informations de défragmentation
    CREATE TABLE #T_INDEXFRAG (
       ObjectName CHAR (255),
       ObjectId INT,
       IndexName CHAR (255),
       IndexId INT,
       Lvl INT,
       CountPages INT,
       CountRows INT,
       MinRecSize INT,
       MaxRecSize INT,
       AvgRecSize INT,
       ForRecCount INT,
       Extents INT,
       ExtentSwitches INT,
       AvgFreeBytes INT,
       AvgPageDensity INT,
       ScanDensity DECIMAL,
       BestCount INT,
       ActualCount INT,
       LogicalFrag DECIMAL,
       ExtentFrag DECIMAL)
     
    -- Ouverture du curseur pour balayer toutes les tables
    OPEN C_TABLES
     
    -- Lecture première lignes
    FETCH NEXT FROM C_TABLES INTO @TABLE_NAME
     
    -- Boucle de balayage
    WHILE @@FETCH_STATUS = 0
    BEGIN
    -- Execute DBCC SHOWCONTIG sur chaque table visée
       INSERT INTO #T_INDEXFRAG 
       EXEC ('DBCC SHOWCONTIG (''' + @TABLE_NAME + ''') 
          WITH TABLERESULTS, ALL_INDEXES, NO_INFOMSGS')
     
    FETCH NEXT FROM C_TABLES INTO @TABLE_NAME
    END
     
    -- Fermeture du curseur et désallocation de l'espace mémoire
    CLOSE C_TABLES
    DEALLOCATE C_TABLES
     
    -- ouverure du curseur sur les index fragmentés d'après les critères fournit
    DECLARE C_INDEX CURSOR
    FOR
    SELECT NEWID() as GUID, ObjectId, IndexId, ObjectName, IndexName
    FROM   #T_INDEXFRAG
    WHERE  CAST(ExtentSwitches AS FLOAT) / CAST(Extents AS FLOAT)      >= @RATIO_EXTENTSWITCHES
       OR  CAST(BestCount AS FLOAT)      / CAST(ActualCount AS FLOAT)  >= @RATIO_COUNT
       OR  CAST(LogicalFrag AS FLOAT)    / CAST(CountPages AS FLOAT)   >= @RATIO_LOGICALFRAG
    ORDER BY GUID
     
    OPEN C_INDEX
     
    -- lecture du premier index à défragmenter
    FETCH NEXT FROM C_INDEX INTO @GUID, @objectid, @indexid, @objectName, @indexName
     
    -- boucle sur les index
    WHILE @@FETCH_STATUS = 0
    BEGIN
       SET @objectName = RTRIM(@objectName)
       SET @indexName = RTRIM(@indexName)
       IF SUBSTRING(CONVERT(CHAR(23), CURRENT_TIMESTAMP, 121), 12, 5) >= @HEURE_LIMITE
          BREAK
       SET @T_BEFORE = CAST(CURRENT_TIMESTAMP AS FLOAT)
       SELECT @QUERY = 'DBCC INDEXDEFRAG (db_name(), ' + RTRIM(@objectid) + ', ' + RTRIM(@indexid) + ')'
       EXEC (@QUERY)
       SET @T_AFTER =  CAST(CURRENT_TIMESTAMP AS FLOAT)
       SET @T_AFTER = (@T_AFTER - @T_BEFORE) * 24
       SET @H = FLOOR(@T_AFTER)
       SET @T_AFTER = (@T_AFTER - FLOOR(@T_AFTER)) * 60
       SET @M = FLOOR(@T_AFTER)
       SET @T_AFTER = (@T_AFTER - FLOOR(@T_AFTER)) * 60
       SET @S = FLOOR(@T_AFTER)
       RAISERROR('Défragmentation effectuée dans la base %s pour l''index %s de l''objet %s en %d heures, %d minutes, %d secondes' , 0, 1, @DATABASE, @indexName, @objectName, @H, @M, @S) WITH LOG
       FETCH NEXT FROM C_INDEX INTO @GUID, @objectid, @indexid, @objectName, @indexName
    END
     
    CLOSE C_INDEX
    DEALLOCATE C_INDEX
     
    DROP TABLE #T_INDEXFRAG
     
     
    GO
    A +

  11. #11
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    344
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 344
    Points : 324
    Points
    324
    Par défaut
    Cool. Ca aussi c'est sympa. On ne le lance que quand necessaire, sans allourdir l'activité du serveur pour rien ...

    La procédure stockée est à créer dans la base master je suppose ... On doit la lancer comment ?
    Si on la lance telle quelle, elle se lancera sur toutes les bases du serveur ? Vu le script je ne pense pas (ou me trompe-je ?)
    On fait un :
    use nom_base
    exec SP_DEFRAG_AUTO

    ou alors:

    SP_DEFRAG_AUTO nom_base
    ??

  12. #12
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 901
    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 901
    Points : 53 143
    Points
    53 143
    Billets dans le blog
    6
    Par défaut
    Elle a été conçue pour être placée dans la base à défragmenter.

    A +

  13. #13
    Membre à l'essai
    Inscrit en
    Août 2009
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 22
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Allez, puisque vous êtes gentil je vous en balance une qui est pas piquée des vers...

    Elle réalise la defrag en tenant compte de la framentation et surtout et choisit de manière aléatoire les tables candidates à une defrag et elle s'arrête automatiquement à une certaine heure. elle a été conçue pour de gros serveurs...

    Si vous ne comprenez pas comment elle fonctionne, ni l'intérêt dites le moi.


    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    CREATE  PROCEDURE SP_DEFRAG_AUTO 
     
    /******************************************************************************
    * DEFRAGMENTATION AUTOMATIQUE DES INDEX PAR SEUIL EN ORDRE ALÉATOIRE          *
    *******************************************************************************
    * Copyright DATA SAPIENS - Frédéric Brouard - 11 février 2005                 *
    ******************************************************************************/
     
           @HEURE_LIMITE         VARCHAR(5) = '08:00', -- doit être de la forme '08:30' : heure limite de début de la dernière opération de défragmentation
           @RATIO_EXTENTSWITCHES FLOAT      = 1.3,     -- doit être d'au moins 1. Valeur inférieure à 1 ignorée. Valeur conseillée pour déclencher une défragementation : 1.3 à 2.0  Déclenche la défragmentation si ExtentSwitches / Extents >= @RATIO_EXTENTSWITCHES alors la défragmentation a lieu
           @RATIO_COUNT          FLOAT      = 1.3,     -- doit être d'au moins 1. Valeur inférieure à 1 ignorée. Valeur conseillée pour déclencher une défragementation : 1.3 à 2.0  Déclenche la défragmentation si BestCount / ActualCount  >= @RATIO_COUNT alors la défragmentation a lieu
           @RATIO_LOGICALFRAG    FLOAT      = 0.2      -- doit être d'au plus 1.  Valeur supérieure à 1 ignorée. Valeur conseillée pour déclencher une défragementation : 0.2 à 0.4. Déclenche la défragmentation si LogicalFrag / CountPages >= @RATIO_LOGICALFRAG
    AS
     
    DECLARE @TABLE_NAME VARCHAR (128)
    DECLARE @QUERY      VARCHAR (255)
    DECLARE @objectid   INT
    DECLARE @indexid    INT
    DECLARE @objectName VARCHAR(256)
    DECLARE @indexName  VARCHAR(256)
    DECLARE @GUID       uniqueidentifier
    DECLARE @T_BEFORE   FLOAT
    DECLARE @T_AFTER    FLOAT
    DECLARE @H          INT
    DECLARE @M          INT
    DECLARE @S          INT
    DECLARE @DATABASE   VARCHAR(128)
     
    SET NOCOUNT ON
     
    SET @DATABASE = DB_NAME(DB_ID())
     
    -- Curseur sur les tables d'exploitation à l'exclusion des tables systèmes et des vues
    DECLARE C_TABLES CURSOR 
    FOR
       SELECT TABLE_NAME
       FROM INFORMATION_SCHEMA.TABLES
       WHERE TABLE_TYPE = 'BASE TABLE'
         AND TABLE_NAME NOT IN (
    'sysusers',
    'systypes',
    'syssubscriptions',
    'sysreferences',
    'syspublications',
    'sysprotects',
    'syspermissions',
    'sysobjects',
    'sysmergesubsetfilters',
    'sysmergesubscriptions',
    'sysmergeschemachange',
    'sysmergepublications',
    'sysmergearticles',
    'sysmembers',
    'sysindexkeys',
    'sysindexes',
    'sysfulltextcatalogs',
    'sysforeignkeys',
    'sysfiles',
    'sysfilegroups',
    'sysdepends',
    'sysconstraints',
    'syscomments',
    'syscolumns',
    'sysarticleupdates',
    'sysarticles',
    'Mssubscriptions',
    'MSsubscription_properties',
    'MSsubscriber_schedule',
    'MSsubscriber_info',
    'MSsnapshot_history',
    'MSsnapshot_agents',
    'MSreplication_subscriptions',
    'MSreplication_objects',
    'MSrepl_version',
    'MSrepl_transactions',
    'MSrepl_originators',
    'MSrepl_errors',
    'MSrepl_commands',
    'Mspublisher_databases',
    'Mspublications',
    'MSpublication_access',
    'MSmerge_tombstone',
    'MSmerge_subscriptions',
    'MSmerge_replinfo',
    'MSmerge_history',
    'MSmerge_genhistory',
    'MSmerge_delete_conflicts',
    'MSmerge_contents',
    'MSmerge_agents',
    'MSlogreader_history',
    'MSlogreader_agents',
    'MSdistributor',
    'MSdistributiondbs',
    'MSdistribution_history',
    'MSdistribution_agents',
    'MSdistpublishers',
    'MSarticles',
    'MSagent_profiles',
    'MSagent_parameters'
    )  
     
     
    -- Creation de la table des informations de défragmentation
    CREATE TABLE #T_INDEXFRAG (
       ObjectName CHAR (255),
       ObjectId INT,
       IndexName CHAR (255),
       IndexId INT,
       Lvl INT,
       CountPages INT,
       CountRows INT,
       MinRecSize INT,
       MaxRecSize INT,
       AvgRecSize INT,
       ForRecCount INT,
       Extents INT,
       ExtentSwitches INT,
       AvgFreeBytes INT,
       AvgPageDensity INT,
       ScanDensity DECIMAL,
       BestCount INT,
       ActualCount INT,
       LogicalFrag DECIMAL,
       ExtentFrag DECIMAL)
     
    -- Ouverture du curseur pour balayer toutes les tables
    OPEN C_TABLES
     
    -- Lecture première lignes
    FETCH NEXT FROM C_TABLES INTO @TABLE_NAME
     
    -- Boucle de balayage
    WHILE @@FETCH_STATUS = 0
    BEGIN
    -- Execute DBCC SHOWCONTIG sur chaque table visée
       INSERT INTO #T_INDEXFRAG 
       EXEC ('DBCC SHOWCONTIG (''' + @TABLE_NAME + ''') 
          WITH TABLERESULTS, ALL_INDEXES, NO_INFOMSGS')
     
    FETCH NEXT FROM C_TABLES INTO @TABLE_NAME
    END
     
    -- Fermeture du curseur et désallocation de l'espace mémoire
    CLOSE C_TABLES
    DEALLOCATE C_TABLES
     
    -- ouverure du curseur sur les index fragmentés d'après les critères fournit
    DECLARE C_INDEX CURSOR
    FOR
    SELECT NEWID() as GUID, ObjectId, IndexId, ObjectName, IndexName
    FROM   #T_INDEXFRAG
    WHERE  CAST(ExtentSwitches AS FLOAT) / CAST(Extents AS FLOAT)      >= @RATIO_EXTENTSWITCHES
       OR  CAST(BestCount AS FLOAT)      / CAST(ActualCount AS FLOAT)  >= @RATIO_COUNT
       OR  CAST(LogicalFrag AS FLOAT)    / CAST(CountPages AS FLOAT)   >= @RATIO_LOGICALFRAG
    ORDER BY GUID
     
    OPEN C_INDEX
     
    -- lecture du premier index à défragmenter
    FETCH NEXT FROM C_INDEX INTO @GUID, @objectid, @indexid, @objectName, @indexName
     
    -- boucle sur les index
    WHILE @@FETCH_STATUS = 0
    BEGIN
       SET @objectName = RTRIM(@objectName)
       SET @indexName = RTRIM(@indexName)
       IF SUBSTRING(CONVERT(CHAR(23), CURRENT_TIMESTAMP, 121), 12, 5) >= @HEURE_LIMITE
          BREAK
       SET @T_BEFORE = CAST(CURRENT_TIMESTAMP AS FLOAT)
       SELECT @QUERY = 'DBCC INDEXDEFRAG (db_name(), ' + RTRIM(@objectid) + ', ' + RTRIM(@indexid) + ')'
       EXEC (@QUERY)
       SET @T_AFTER =  CAST(CURRENT_TIMESTAMP AS FLOAT)
       SET @T_AFTER = (@T_AFTER - @T_BEFORE) * 24
       SET @H = FLOOR(@T_AFTER)
       SET @T_AFTER = (@T_AFTER - FLOOR(@T_AFTER)) * 60
       SET @M = FLOOR(@T_AFTER)
       SET @T_AFTER = (@T_AFTER - FLOOR(@T_AFTER)) * 60
       SET @S = FLOOR(@T_AFTER)
       RAISERROR('Défragmentation effectuée dans la base %s pour l''index %s de l''objet %s en %d heures, %d minutes, %d secondes' , 0, 1, @DATABASE, @indexName, @objectName, @H, @M, @S) WITH LOG
       FETCH NEXT FROM C_INDEX INTO @GUID, @objectid, @indexid, @objectName, @indexName
    END
     
    CLOSE C_INDEX
    DEALLOCATE C_INDEX
     
    DROP TABLE #T_INDEXFRAG
     
     
    GO
    A +
    Bonjour,


    Comment bien utiliser le script que vous avez posté ?

    Est-t-il possible de le mettre dans un plan de maintenance ?

    Y-a-t'il des modifications a apporter ? Et où ?

    Ce script fait une défragmentation des indexes mais sont il compris entre 0 et 30 ?

    Désolé pour les questions de novice, mais j'en suis un.

    Merci d'avance

  14. #14
    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,

    Allez, voici une procédure stockée que j'avais écrite pour défragmenter les index en utilisant les DMVs de SQL Server 2005, et qui fonctionne sous SQL Server 2008.

    Depuis j'en ai écrit une plus futée que je vais publier

    Comment bien utiliser le script que vous avez posté ?
    Il suffit de l'exécuter (celui de SQLPro comme le mien) dans le contexte de la base de données contenant les indexes à défragmenter.

    Vous pouvez faire cela dans l'analyseur de requêtes si vous êtes sous SQL Server 2000, ou dans SQL Server Management Studio si vous êtes sous SQL Server 2005 ou 2005 ou Denali

    Est-t-il possible de le mettre dans un plan de maintenance ?
    Rien ne vous en empêche, mais il est plus simple de l'appeler directement dans un job de l'agent SQL Server

    Y-a-t'il des modifications a apporter ? Et où ?
    Non, vous pouvez l'utiliser telle quelle

    Ce script fait une défragmentation des indexes mais sont il compris entre 0 et 30 ?
    Non, il fait la défragmentation des indexes fragmentés à plus de 30%.
    En deçà ça ne vaut pas le coup de les défragmenter.
    Vous pouvez néanmoins les réorganiser (DBCC INDEXDEFRAG ou ALTER INDEX ... REORGANIZE) si leur fragmentation est entre 10 et 30%
    Pareillement, défragmenter une petite table n'a aucune utilité.

    Désolé pour les questions de novice, mais j'en suis un.
    On est tous passés par là

    @++

  15. #15
    Membre à l'essai
    Inscrit en
    Août 2009
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 22
    Points : 14
    Points
    14
    Par défaut
    Merci d'avoir pris le temps de répondre a toutes mes questions.

    Néanmoins j'en ai une autre , je suis sous SSMS 2005 avec server sql 2000.
    Je vois les plans de maintenance, sauf que je n'ai pas la possibilité d'en créer.

    Je me suis connecté avec le compte d'un autre utilisateur sur le pc que j'utilise, avec son compte on a la possibilité d'en créer mais pas avec le mien.


    note: on a vérifié les rôles et droits ce sont les mêmes help.

  16. #16
    Membre à l'essai
    Inscrit en
    Août 2009
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 22
    Points : 14
    Points
    14
    Par défaut
    Je pense avoir trouvé cela vient du fait que je me connecte sur Sql Server 2000 et qu'il ne prend pas en charge .

  17. #17
    Expert éminent sénior
    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 : 45
    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
    Points : 12 891
    Points
    12 891
    Par défaut
    Bonjour,

    Tout à fait, les plans de maintenance sous SQL Server 2005 sont très différents des plans de maintenance sur SQL Server 2000.

    Vous pouvez néanmois voir vos plans de maintenance sont le noeud LEGACY.
    Vous pourret toutefois les modifier avec SSMS 2005 en installant les outils de compatibilité 2005. Une autre solution est d'installer Enterprise Manager (SQL 2000) sur votre poste.

    ++

Discussions similaires

  1. [Windows]accès base de registre windows
    Par Greg01 dans le forum API standards et tierces
    Réponses: 27
    Dernier message: 05/06/2007, 15h14
  2. taille maximale d'une base de donnée paradox
    Par Anonymous dans le forum Paradox
    Réponses: 5
    Dernier message: 14/02/2004, 17h39
  3. sauver une base
    Par phil_java dans le forum Administration
    Réponses: 3
    Dernier message: 07/03/2003, 17h08
  4. [Concept] Stabilité d'une base de donnée
    Par lassmust dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 03/07/2002, 16h16
  5. Utilisez vous la base de registres ?
    Par gRRosminet dans le forum C++Builder
    Réponses: 8
    Dernier message: 04/06/2002, 13h55

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