2017-02-12 1 views
2

J'ai une table de base de données qui contient 900 millions d'enregistrements. Je suis dans une situation où j'ai besoin de mettre à jour 4 clés différentes dans cette table, en les joignant à une dimension et en plaçant la clé de la table de faits à la clé de la dimension. J'ai écrit 4 scripts SQL différents (voir l'exemple ci-dessous) pour effectuer la mise à jour, mais le problème est qu'il prend trop de temps à s'exécuter. La requête est en cours depuis plus de 20 heures et je ne sais même pas jusqu'où elle ira et combien de temps cela prendra. Est-ce que je peux faire quelque chose pour améliorer cela, alors cela ne prend que quelques heures à compléter. Est-ce que l'ajout d'index améliorerait cela?SQL - Performances de requête de mise à jour pour les enregistrements de grande table (900 millions)

UPDATE f 
SET f.ClientKey = c.ClientKey 
FROM dbo.FactSales f 
JOIN dbo.DimClient c 
ON f.ClientId = c.ClientId 
+1

Vous n'avez pas testé sur un sous-ensemble plus petit avant de l'exécuter sur une table de 900 000 000 lignes? Aie. Le pire des cas serait un index sur la colonne mise à jour. Je préférerais créer une nouvelle table, écrire une seule sélection avec toutes les 4 jointures, insérer/sélectionner, supprimer et renommer. – dnoeth

+0

Si (ou plus probable "quand") cela va revenir en arrière ... ouch ... –

Répondre

0
  1. Script clés étrangères. Laisse-les tomber.
  2. Index de scripts sur les colonnes mises à jour (qui ne font pas partie de la condition). Laisse-les tomber.
  3. Désactiver les déclencheurs s'ils existent.
  4. Désactiver tous les processus pouvant effectuer des verrous (= all, include select).
  5. Mettez à jour vos clés. Recréez vos clés étrangères, vos index, activez les déclencheurs.
  6. Soyez heureux.

Et de commenter pour 5 - préparer votre clé primaire à partir de la table de destination avec tout le nouveau code source seulement et faire une déclaration. Cela signifie un coût moindre sur les jointures et il n'y aura qu'une seule jointure.

0

peut l'utiliser pour ne pas remplir le journal des transactions

select 1 
while(@@rowcount > 0) 
begin 
    UPDATE f 
    SET top (100000) f.ClientKey = c.ClientKey 
    FROM dbo.FactSales f 
    JOIN dbo.DimClient c 
    ON f.ClientId = c.ClientId 
    AND f.ClientKey != c.ClientKey 
end 

Si vous devez mettre à jour 4 clés différentes les faire alors tout à la fois
La plupart du coût est acquiert verrouillage

Désactiver f .ClientKey, exécutez la mise à jour, puis le reconstruire

Si vous êtes sûr DimClient ne va pas changer with (nolock) mais que vous devez être sûr

Si vous êtes le seul processus qui a besoin de mettre à jour FactSales, prenez un blocage de tablock

+0

Vous allez scanner les données encore et encore et encore et encore et encore et encore ... –

+0

@DuduMarkovitz Correct. Est-ce que remplir le journal des transactions et tout avoir de mieux en sortir? – Paparazzi

+0

Je n'ai pas eu votre intention –

0

Créez un nouveau tableau avec les valeurs correctes. Ajouter des index, des contraintes après. Déposez le tableau existant et renommez le nouveau en un existant dans une transaction si cela est possible.