2009-10-15 29 views
1

Édition: Im en cours d'exécution SQL Server 2008Comment rapidement dupliquer des lignes dans SQL

J'ai environ 400 000 lignes dans ma table. Je voudrais dupliquer ces lignes jusqu'à ce que ma table ait 160 millions de lignes ou plus. J'ai utilisé une déclaration comme ceci:

INSERT INTO [DB].[dbo].[Sales] 
      ([TotalCost] 
      ,[SalesAmount] 
      ,[ETLLoadID] 
      ,[LoadDate] 
      ,[UpdateDate]) 
SELECT [TotalCost] 
     ,[SalesAmount] 
     ,[ETLLoadID] 
     ,[LoadDate] 
     ,[UpdateDate] 
    FROM [DB].[dbo].[Sales] 

Ce processus est très lent. et je dois ré-émettre la question un grand nombre de fois Y at-il une meilleure manière de faire ceci?

Répondre

3

Pour ce faire, de nombreux inserts vous souhaitez désactiver tous les index et les contraintes (y compris les clés étrangères), puis exécutez une série de:

INSERT INTO mytable 
SELECT fields FROM mytable 

Si vous devez spécifier ID, choisissez un nombre comme 80000000 et inclure dans la liste SELECT ID+80000000. Exécuter autant de fois que nécessaire (pas plus de 10 car il devrait doubler à chaque fois).

De même, ne s'exécutent pas dans une transaction. Le surcoût d'un tel ensemble de données sera énorme. Vous manquerez probablement de ressources (segments de restauration ou tout ce que votre base de données utilise) de toute façon.

Ensuite, réactivez toutes les contraintes et tous les index. Cela prendra un longtemps mais dans l'ensemble il sera plus rapide que d'ajouter aux index et de vérifier les contraintes sur une base par ligne.

0

Vous n'indiquez pas votre base de données SQL, mais la plupart disposent d'un outil de chargement en bloc pour gérer ce scénario. Vérifiez les docs. Si vous devez le faire avec INSERTs, supprimez d'abord tous les index de la table et réappliquez-les après que les données sont INSERTES; cela sera généralement beaucoup plus rapide que l'indexation pendant l'insertion.

1

Comme chaque fois que vous exécutez cette commande il à double la taille de votre table, vous ne devrez exécuter environ 9 fois (400.000 * 2 = 204800000). Oui, cela peut prendre un certain temps car la copie d'autant de données prend du temps.

1

La vitesse de l'insertion dépendra d'un certain nombre de choses ... la vitesse du disque physique, les index, etc. Je recommande de supprimer tous les index de la table et de les rajouter lorsque vous avez terminé. Si la table est fortement indexée, cela devrait aider un peu.

Vous devriez pouvoir exécuter cette requête plusieurs fois dans une boucle jusqu'à ce que le nombre de lignes souhaité soit atteint. Chaque fois que vous l'exécutez vous doublera les données, vous vous retrouverez avec:

400,000 
800,000 
1,600,000 
3,200,000 
6,400,000 
12,800,000 
25,600,000 
51,200,000 
102,400,000 
204,800,000 

Après neuf exécutions.

+0

Droite. le problème est juste que cela prend comme 10 minutes pour les premières itérations. J'imagine que le temps va évoluer proportionnellement, donc il faut vraiment comme heures pour dupliquer une table de cette taille? – abudker

+0

Avez-vous essayé de supprimer des index? À un moment donné, il suffira de * prendre autant de temps * pour écrire autant de données. –

0

Cela peut prendre un certain temps à s'exécuter ... vous pouvez désactiver la journalisation pendant la création de vos données.

INSERT INTO [DB].[dbo].[Sales] (
      [TotalCost] ,[SalesAmount] ,[ETLLoadID] 
      ,[LoadDate] ,[UpdateDate] 
) 
SELECT s.[TotalCost] ,s.[SalesAmount] ,s.[ETLLoadID] 
     ,s.[LoadDate] ,s.[UpdateDate] 
FROM [DB].[dbo].[Sales] s (NOLOCK) 
CROSS JOIN (SELECT TOP 400 totalcost FROM [DB].[dbo].[Sales] (NOLOCK)) o 
+0

Que fait cette ligne de la commande? – abudker

+0

Je l'ai utilisé comme une jointure cartésienne http://en.wikipedia.org/wiki/Cartesian_product basiscly il se retrouverait avec 400 fois le nombre d'enregistrements dans les ventes.J'ai dit le top 400 parce que 400 * 400 000 est 160 millions. –

+0

Cette méthode la plus simple et la plus propre serait de continuer à doubler l'entrée comme d'autres l'ont suggéré. –

Questions connexes