web-dev-qa-db-fra.com

Comment copier une énorme table de données dans une autre table dans SQL Server

J'ai une table avec 3,4 millions de lignes. Je veux copier toutes ces données dans une autre table.

J'exécute cette tâche en utilisant la requête ci-dessous:

select * 
into new_items 
from productDB.dbo.items

J'ai besoin de connaître la meilleure façon possible d'accomplir cette tâche.

29
sqlchild

Si vous copiez dans une table nouvelle, le moyen le plus rapide est probablement ce que vous avez dans votre question, sauf vos lignes sont très grandes.

Si vos lignes sont très grandes, vous souhaiterez peut-être utiliser les fonctions d'insertion en bloc dans SQL Server. Je pense que vous pouvez les appeler depuis C #.

Ou vous pouvez d'abord télécharger ces données dans un fichier texte, puis les copier en bloc (bcp). Cela a l'avantage supplémentaire de vous permettre d'ignorer les clés, les index, etc.

Essayez également l'utilitaire d'importation/exportation fourni avec SQL Management Studio; Je ne sais pas si ce sera aussi rapide qu'une copie en bloc simple, mais cela devrait vous permettre d'ignorer l'étape intermédiaire de l'écriture en tant que fichier plat et de copier directement directement de table en table, ce qui pourrait être un peu plus rapide que votre SELECT INTO déclaration.

15
Stephen Chung

J'ai eu le même problème, sauf que j'ai une table avec 2 milliards de lignes, donc le fichier journal augmenterait sans fin si je le faisais, même avec le modèle de récupération défini sur Bulk-Logging:

insert into newtable select * from oldtable

J'opère donc sur des blocs de données. De cette façon, si le transfert est interrompu, il vous suffit de le redémarrer. De plus, vous n'avez pas besoin d'un fichier journal aussi grand que la table. Vous semblez également obtenir moins d'E/S tempdb, vous ne savez pas pourquoi.

set identity_insert newtable on
DECLARE @StartID bigint, @LastID bigint, @EndID bigint
select @StartID = isNull(max(id),0) + 1
from newtable

select @LastID = max(ID)
from oldtable

while @StartID < @LastID
begin
    set @EndID = @StartID + 1000000

    insert into newtable (FIELDS,GO,HERE)
    select FIELDS,GO,HERE from oldtable (NOLOCK)
    where id BETWEEN @StartID AND @EndId

    set @StartID = @EndID + 1
end
set identity_insert newtable off
go

Vous devrez peut-être modifier la façon dont vous traitez les ID, cela fonctionne mieux si votre table est regroupée par ID.

71
Mathieu Longtin

J'ai travaillé avec notre DBA pour copier une table d'audit avec 240 millions de lignes dans une autre base de données.

En utilisant une simple sélection/insertion, vous avez créé un énorme fichier tempdb.

L'utilisation d'un assistant d'importation/exportation a fonctionné mais a copié 8 millions de lignes en 10 minutes

Création d'un package SSIS personnalisé et ajustement des paramètres copiés 30 millions de lignes en 10 minutes

Le package SSIS s'est avéré être le plus rapide et le plus efficace pour nos besoins

Comte

11
earlxtr

Voici une autre façon de transférer de grandes tables. Je viens de transférer 105 millions de lignes entre deux serveurs en utilisant cela. Assez rapide aussi.

  1. Cliquez avec le bouton droit sur la base de données et choisissez Tâches/Exporter les données .
  2. Un assistant vous guidera à travers les étapes, mais vous choisir votre client SQL Server comme source de données et cible vous permettra de sélectionner la base de données et les tables que vous souhaitez transférer.

Pour plus d'informations, voir https://www.mssqltips.com/sqlservertutorial/202/simple-way-to-export-data-from-sql-server/

5
user489998

S'il s'agit d'une importation unique, l'utilitaire d'importation/exportation dans SSMS fonctionnera probablement le plus facilement et le plus rapidement. SSIS semble également fonctionner mieux pour importer des ensembles de données volumineux qu'un INSERT simple.

BULK INSERT ou BCP peut également être utilisé pour importer de grands jeux d'enregistrements.

Une autre option serait de supprimer temporairement tous les index et contraintes de la table dans laquelle vous importez et de les rajouter une fois le processus d'importation terminé. Un INSERT simple qui a précédemment échoué peut fonctionner dans ces cas.

Si vous rencontrez des délais d'expiration ou des problèmes de verrouillage/blocage lorsque vous passez directement d'une base de données à une autre, vous pouvez envisager de passer d'une base de données à TEMPDB, puis de passer de TEMPDB à l'autre base de données, car cela minimise les effets des processus de verrouillage et de blocage sur de chaque côté. TempDB ne bloquera ni ne verrouillera la source et ne bloquera pas la destination.

Ce sont quelques options à essayer.

-Eric Isaacs

3
Eric Isaacs

Le travail d'insertion/sélection simple de sp est excellent jusqu'à ce que le nombre de lignes dépasse 1 mil. J'ai vu le fichier tempdb exploser en essayant d'insérer/sélectionner 20 mil + lignes. La solution la plus simple est SSIS définissant le tampon de taille de ligne de lot sur 5000 et le tampon de taille de validation sur 1000.

1
user10198537

Si vous vous concentrez sur l'archivage (DW) et que vous traitez avec VLDB avec plus de 100 tables partitionnées et que vous souhaitez isoler la plupart de ces travaux gourmands en ressources sur un serveur non productif (OLTP), voici une suggestion (OLTP -> DW) 1) Utiliser sauvegarde/restauration pour obtenir les données sur le serveur d'archives (donc maintenant, sur Archive ou DW, vous aurez la base de données Stage et Target) 2) Base de données Stage: utilisez le commutateur de partition pour déplacer les données vers la table des étapes correspondante
3) Utilisez SSIS pour transférer des données de la base de données intermédiaire vers la base de données cible pour chaque table intermédiaire des deux côtés 4) Base de données cible: utilisez le commutateur de partition sur la base de données cible pour déplacer les données de l'étape vers la table de base J'espère que cela vous aidera.

0
DB Bee