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.
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.
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.
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
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.
Pour plus d'informations, voir https://www.mssqltips.com/sqlservertutorial/202/simple-way-to-export-data-from-sql-server/
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
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.
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.