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 :

Alter ou Drop et Create


Sujet :

MS SQL Server

  1. #1
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut Alter ou Drop et Create
    Bonsoir à tous,
    J'ai lu quelque part, sur les blogs de développez il me semble qu'il était contre-performant de réaliser un ALTER sur une table (en particulier volumineuse) plutôt que de créer une nouvelle table en y copiant les données.
    Dans mes souvenirs, le cas d'un ALTER qui modifiait le type d'une colonne pour la rendre plus large faisait perdre l'ancien espace dans chaque page de données..

    Malheureusement je ne retrouve plus le billet qui en parlait... Si votre mémoire est meilleur que la mienne, je suis à la recherche du lien
    De plus, est-ce qu'il est possible de retrouver dans une base toutes les tables qui ont pu subir ce genre de modification ?

    Merci pour vos souvenirs.
    Alexandre Chemla - Consultant MS BI chez Masao

  2. #2
    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
    J'ai lu quelque part, sur les blogs de développez il me semble qu'il était contre-performant de réaliser un ALTER sur une table (en particulier volumineuse) plutôt que de créer une nouvelle table en y copiant les données.
    Tout dépend ce que fait le ALTER.

    Malheureusement je ne retrouve plus le billet qui en parlait... Si votre mémoire est meilleur que la mienne, je suis à la recherche du lien
    Peut-être ici

    ++

  3. #3
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Citation Envoyé par mikedavem Voir le message
    Tout dépend ce que fait le ALTER.
    Peut-être ici
    ++
    Ahhhh je me souvenais bien que je l'avais vu pas loin d'ici. je l'avais même commenté


    Dans un des cas, je passe d'un INT à du DECIMAL(19,4) :p
    Mais l'idée est aussi de retrouver toutes les tables volumineuses qui ont pu "souffrir" de ces alter.
    Alexandre Chemla - Consultant MS BI chez Masao

  4. #4
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Je reviens un peu sur ma question...

    Je suis en train de chercher la liste des tables qui ont pu subir une opération d'ALTER. Pour cela j'utilise la requête suivante qui me retourne les tables pour lesquelles la somme des taille des colonnes est différente du MAX de l'ofset de départ + la taille de cette même colonne :
    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
    ;
    WITH MaxOffsetTable AS (
    SELECT
    	tb.name	AS TableName
        ,MAX(leaf_offset)	AS DebutDerniereColonne
    --    ,column_id			AS IdDerniereColonne
    FROM 
    	sys.system_internals_partition_columns PC
    	INNER JOIN sys.partitions AS P
    		ON P.partition_id = PC.partition_id
    	INNER JOIN sys.columns AS C
    		ON C.column_id = PC.partition_column_id
    		AND C.object_id = P.object_id
    	INNER JOIN sys.tables tb
    		ON tb.object_id = P.object_id
    GROUP BY 
    	tb.name
    ),
    TotalTable AS (
    SELECT
    	tb.name	AS TableName
        ,4+ SUM(max_inrow_length)	AS TailleTotale
    FROM 
    	sys.system_internals_partition_columns PC
    	INNER JOIN sys.partitions AS P
    		ON P.partition_id = PC.partition_id
    	INNER JOIN sys.columns AS C
    		ON C.column_id = PC.partition_column_id
    		AND C.object_id = P.object_id
    	INNER JOIN sys.tables tb
    		ON tb.object_id = P.object_id
    GROUP BY 
    	tb.name
    )
    select * from (
    SELECT
    	tb.name	AS TableName
    	,SUM(leaf_offset + max_inrow_length)	AS TailleColonnes
    	,SUM(TotalTable.TailleTotale)			AS TailleTotale
    FROM 
    	sys.system_internals_partition_columns PC
    	INNER JOIN sys.partitions AS P
    		ON P.partition_id = PC.partition_id
    	INNER JOIN sys.columns AS C
    		ON C.column_id = PC.partition_column_id
    		AND C.object_id = P.object_id
    	INNER JOIN sys.tables tb
    		ON tb.object_id = P.object_id
    	INNER JOIN MaxOffsetTable
    		ON MaxOffsetTable.TableName = tb.name
    		AND MaxOffsetTable.DebutDerniereColonne = leaf_offset
    	INNER JOIN TotalTable
    		ON TotalTable.TableName = tb.name
    GROUP BY 
    	tb.name
    ) t
    WHERE 
    	TailleColonnes <> TailleTotale
    Je me retrouve alors avec un certains nombre de table, MAIS avec la requête suivante que l'on trouve dans le billet, je trouve des tables (la plupart) pour lesquelles le "leaf_ofset" prends des valeurs négatives
    Je précise que les colonnes en question sont des VARCHAR, non MAX


    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
    SELECT
    	tb.name	AS TableName,
        C.name AS column_name,
        C.column_id,
        PC.max_inrow_length,
        PC.system_type_id,
        PC.leaf_offset
     
        , PC.partition_id
        , P.*
    FROM 
    	sys.system_internals_partition_columns PC
    	INNER JOIN sys.partitions AS P
    		ON P.partition_id = PC.partition_id
    		AND P.index_id in (0, 1)
    	INNER JOIN sys.columns AS C
    		ON C.column_id = PC.partition_column_id
    		AND C.object_id = P.object_id
    	INNER JOIN sys.tables tb
    		ON tb.object_id = P.object_id
    WHERE 
    	P.object_id = OBJECT_ID('DimIndicateur')
    P.S. : J'ai du ajouter un filtre "sys.partitions.index_id in (0, 1)" pour ne pas récupérer les infos des indexs et me trouver alors avec doubons sur les colonnes.
    Alexandre Chemla - Consultant MS BI chez Masao

  5. #5
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    En fait, les -1 sont bien pour le cas des types VARCHAR. De plus, les bit ont également un traitement particulier
    Ça devient compliqué pour détecter les tables "fautives"
    Alexandre Chemla - Consultant MS BI chez Masao

  6. #6
    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
    Tu ne pourras pas utiliser la vue système sys.system_internals_partition_columns. La colonne leaf_offset n'est réellement utilisable que pour les types de données fixes car la longueur est prédictible dans ce cas. Avec les types de données variables la longueur est directement dépendante de la donnée donc déterminer à l'avance le leaf_offset n'est pas possible. En revanche les numéros s'incrémentent pour déterminer le nombre de colonnes variables dans ce cas. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE TABLE T_TEST4
    ( 
    texte1 VARCHAR(50) NOT NULL,
    texte2 VARCHAR(50) NOT NULL,
    boll BIT NOT NULL,
    id SMALLINT NOT NULL 
    );
     
    INSERT T_TEST4 VALUES (REPLICATE('T', 25), REPLICATE('T', 30), 1, 1);
    donnera cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    column_name	column_id	max_inrow_length	system_type_id	leaf_offset	max_length
    texte1	1	50	167	-1	50
    texte2	2	50	167	-2	50
    boll	3	1	104	4	1
    id	4	2	52	5	2
    Une modification de la longueur d'une colonne variable donnera ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ALTER TABLE T_TEST4
    ALTER COLUMN texte1 VARCHAR(25); 
    GO
    ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    texte2	2	50	167	-2	50
    boll	3	1	104	4	1
    id	4	2	52	5	2
    texte1	1	25	167	-3	25
    Tu remarqueras que -1 a disparu pour laisser la place à -3. De manière générale si tes tables possèdent des indexes cluster, le fait de les reconstruire permettra de régler le problème d'espace inutilisé par les changements effectués sur tes colonnes.

    ++

  7. #7
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Merci pour la précision. Du coup pour ces longueur varchar, l'emplacement de démarrage de chacun des champs dépend complètement de la longueur de la valeur ? Il n'y a plus rien de fixe.

    Détecter toutes les tables à "problème" devient donc plus compliqué et il vaut mieux alors faire une reconstruction complète de toutes celles-ci.

    En terme de performance, pour des tables volumineuses de plusieurs centaines de millions de lignes, pour effectuer une modification de type vaut-il mieux alors faire comme le propose SSMS en reconstruisant une nouvelle table ou plutôt conserver cette commande ALTER et le faire suivre d'un ALTER ?

    Sur une base de production, l'avantage de la nouvelle table est de ne pas bloquer l'accès à l'ancienne, alors que le ALTER pose un verrou ?
    Alexandre Chemla - Consultant MS BI chez Masao

  8. #8
    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
    En terme de performance, pour des tables volumineuses de plusieurs centaines de millions de lignes, pour effectuer une modification de type vaut-il mieux alors faire comme le propose SSMS en reconstruisant une nouvelle table ou plutôt conserver cette commande ALTER et le faire suivre d'un ALTER ?
    Tout dépend le changement comme je te disais :

    Une commande ALTER qui supprime une colonne, ajoute une colonne avec NULL par défaut ou augmente la longueur d'une colonne ne touchera pas aux données et il n'y aura pas besoin de faire une analyse ligne à ligne des données.

    Une commande ALTER qui annule l'acceptation des absences de valeurs (NULL) ou diminue la longueur d'une colonne devra examiner et valider l'ensemble des valeurs des colonnes concernées sans pour autant y toucher. Sur une table volumineuse le processus peut prendre du temps.

    Enfin d'autres changements impliquent un changement physique au niveau des lignes de données comme l'ajout d'une colonne avec par défaut une valeur non NULL. Dans ce cas, chaque changement de ligne doit être loggé dans le journal des transactions. Bien entendu le processus peut être très long ici et consommateur de ressources.

    Sur une base de production, l'avantage de la nouvelle table est de ne pas bloquer l'accès à l'ancienne, alors que le ALTER pose un verrou ?
    Effectivement un alter table requier un verrou de type schéma SCH-M

    ++

  9. #9
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Merci pour ces dernières précisions
    Alexandre Chemla - Consultant MS BI chez Masao

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Drop et create Partition
    Par DevMan2005 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 30/11/2007, 11h57
  2. Drop Table ; Create Table
    Par monoar dans le forum Ruby on Rails
    Réponses: 2
    Dernier message: 23/07/2007, 14h57
  3. drop avant create table ?
    Par ]matmat[ dans le forum SQL
    Réponses: 5
    Dernier message: 28/08/2006, 21h27
  4. alter table : drop column
    Par delas dans le forum DB2
    Réponses: 1
    Dernier message: 26/06/2006, 13h42
  5. [9i] syntaxe de ALTER TABLE ... DROP PARTITION
    Par dyvim dans le forum Oracle
    Réponses: 1
    Dernier message: 03/02/2006, 11h52

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