Bulk Insert pour Oracle à l'aide .NET
Quel est le moyen le plus rapide pour faire de l'instruction Bulk insert pour Oracle à l'aide .NET? J'ai besoin de transférer environ 160K des enregistrements à l'aide .NET pour Oracle. Actuellement, je suis en utilisant instruction insert et de l'exécuter 160K fois.Il faut environ 25 minutes pour le remplir. La source de données est stockée dans une Table de données, comme un résultat de requête à partir d'une autre base de données (MySQL),
Est-il une meilleure façon de le faire?
MODIFIER : je suis actuellement en utilisant le Système.Les données.OracleClient, mais prêt à accepter des solutions à l'aide d'un autre fournisseur (ODP.NET, DevArt, etc..)
- Quel est le problème avec un utilitaire comme SQL*Loader?
- Avez-vous essayé de DevArt? Je me demandais si Devart a OracleBulkCopy.
Vous devez vous connecter pour publier un commentaire.
Je suis de chargement de 50 000 enregistrements dans 15 secondes à l'aide de la Matrice de Liaison dans ODP.NET
Il fonctionne par à plusieurs reprises d'appeler une procédure stockée que vous spécifiez (et dans lequel on peut faire des mises à jour/insertions/suppressions), mais il passe les multiples valeurs de paramètre .NET à la base de données en vrac.
Au lieu de spécifier une valeur unique pour chaque paramètre à la procédure stockée que vous spécifiez une tableau de valeurs pour chaque paramètre.
Oracle passe le paramètre de tableaux à partir de .NET à la base de données en une seule fois, et ensuite à plusieurs reprises appelle la procédure stockée que vous spécifiez à l'aide des valeurs des paramètres que vous avez spécifiés.
http://www.oracle.com/technetwork/issue-archive/2009/09-sep/o59odpnet-085168.html
/Damian
J'ai récemment découvert une classe spécialisée qui est génial pour un bulk insert (ODP.NET). Oracle.DataAccess.Client.OracleBulkCopy! Il prend un datatable en tant que paramètre, puis vous appelez WriteTOServer méthode...il est très rapide et efficace, bonne chance!!
La solution de Rob Stevenson-Legget est lent parce qu'il ne se lient pas à ses valeurs, mais il l'utilise de la chaîne.Format( ).
Lorsque vous demandez à Oracle pour exécuter une instruction sql, il commence par le calcul de la valeur de cette déclaration. Après qu'il recherche dans une table de hachage qu'il sait déjà de cette déclaration. Si il le sait déjà énoncé, il peut récupérer son chemin d'exécution à partir de cette table de hachage et de l'exécution de cette instruction très rapides, car l'Oracle a exécuté cette déclaration avant. Cela s'appelle la bibliothèque de cache et il ne fonctionne pas correctement si vous n'avez pas lier vos instructions sql.
Par exemple ne pas faire:
int n;
mais n':
Pas à l'aide de paramètres peuvent également provoquer une injection sql.
SQL Server SQLBulkCopy est absolument rapide. Malheureusement, j'ai trouvé que OracleBulkCopy est beaucoup plus lent. Aussi, il a des problèmes:
utilisation OracleBulkCopy. Si une violation de clé primaire se produit, un ORA-26026
est soulevée et il semble irrécupérable. Essayer de reconstruire les
l'indice n'aide pas et les insérer sur la table échoue,
aussi normale inserts.
OracleBulkCopy parfois coincé à l'intérieur de WriteToServer. Le problème
semble dépendre de la taille du lot. Dans mes données de test, le problème serait
arriver exactement au même point dans mon test lorsque je le répète, est. L'utilisation d'un
plus grande ou plus petite taille de lot, et le problème ne se produit pas. Je vois
que la vitesse est plus irrégulière sur de plus grandes tailles de lots, ce points
des problèmes liés à la gestion de la mémoire.
Système.Les données.OracleClient.OracleDataAdapter est plus rapide que OracleBulkCopy si vous voulez remplir un tableau avec des petits dossiers, mais de nombreuses lignes. Vous devez ajuster la taille du lot cependant, l'optimum BatchSize pour OracleDataAdapter est plus petite que pour OracleBulkCopy.
J'ai couru mon test sur une machine Windows 7 avec un x86 exécutable 32 bits ODP.Net client 2.112.1.0. . Le OracleDataAdapter est la partie du Système.Les données.OracleClient 2.0.0.0. Mon test est environ 600 000 lignes avec une taille d'enregistrement max. 102 octets (taille moyenne de 43 caractères). Source de données est de 25 MO fichier texte, lire en ligne en ligne sous forme de flux.
Dans mon test, j'ai construit les données d'entrée de la table pour une table fixe à la taille et ensuite utilisé soit OracleBulkCopy ou OracleDataAdapter pour copier le bloc de données pour le serveur. J'ai quitté BatchSize comme 0 dans OracleBulkCopy (façon à ce que le contenu du tableau est copié comme un lot) et le régler à la taille de la table dans OracleDataAdapter (encore une fois qui doit créer un seul lot de fabrication à l'interne).
Les meilleurs résultats:
Pour la comparaison:
Même ordinateur client, serveur de test, SQL Server 2008 R2. Pour SQL Server, bulk copy est le meilleur moyen d'aller. Il est non seulement plus rapide, mais la charge du serveur est également plus faible que lors de l'utilisation de la carte de données. Il est dommage que OracleBulkCopy n'offre pas tout à fait la même expérience - la BulkCopy API est beaucoup plus facile à utiliser que DataAdapter.
Vraiment un moyen rapide de résoudre ce problème est de faire un lien de base de données à partir de la base de données Oracle pour la base de données MySQL. Vous pouvez créer une base de données des liens vers d'autres bases de données Oracle. Après avoir créé le lien de base de données, vous pouvez récupérer vos données à partir de la base de données MySQL avec une ... create table mydata select * from ... déclaration. Ceci est appelé hétérogène de la connectivité. De cette façon, vous n'avez pas à faire quoi que ce soit dans votre .net application pour déplacer les données.
Une autre façon est d'utiliser ODP.NET. Dans ODP.NET vous pouvez utiliser le OracleBulkCopy de classe.
Mais je ne pense pas que l'insertion 160k enregistrements dans une table Oracle avec le Système.Les données.OracleClient devrait prendre 25 minutes. Je pense que vous vous engagez à de trop nombreuses reprises. Et ne vous liez vos valeurs à l'instruction insert avec des paramètres ou avez-vous concaténer vos valeurs. La liaison est beaucoup plus rapide.
Pour le suivi de Théo suggestion avec mes conclusions (excuses - je n'aie pas assez de réputation pour ce post un commentaire)
Première, c'est comment utiliser plusieurs paramètres nommés:
Cependant, je n'ai vu aucune variation de vitesse entre:
Je suis en utilisant le Système.Les données.OracleClient, la suppression et l'insertion de 2500 lignes à l'intérieur d'une transaction
Oracle dit (http://www.oracle.com/technology/products/database/utilities/htdocs/sql_loader_overview.html)
Mon expérience est que leur chargeur charge leurs tables plus vite que tout autre.
Trouver liés exemples un peu confus, j'ai travaillé sur certains de code qui montre un travail tableau insérer dans une table de test (jkl_test). Voici le tableau:
Est ici .Net code pour une simple application Console qui se connecte à Oracle à l'aide de ODP.Net et insère un tableau de 5 entiers:
Je suppose que OracleBulkCopy est l'un des moyens les plus rapides. J'ai eu quelques difficultés à apprendre, que j'avais besoin d'une nouvelle version ODAC. Cf. Où est de type [Oracle.DataAccess.Client.OracleBulkCopy] ?
Voici la PowerShell de code à copier à partir d'une requête dans une adaptées existantes table Oracle. J'ai essayé de Sql-Server une source de données, mais d'autres OLE-DB sources ira.
BTW: je l'utilise pour copier le tableau avec CLOB colonnes. Je n'ai pas de travail à l'aide de serveurs liés cf. question sur dba. Je n'ai pas réessayer lié sert avec le nouveau ODAC.
Si vous utilisez non géré client oracle (Oracle.DataAccess), alors le moyen le plus rapide est d'utiliser OracleBulkCopy, comme il a été indiqué par Tarik.
Si vous êtes en utilisant les dernières géré client oracle (Oracle.ManagedDataAccess), alors le moyen le plus rapide est d'utiliser la matrice de liaison, comme cela a été signalé par Damien. Si vous souhaitez conserver votre code d'application propre de la matrice de liaison de détails, vous pouvez écrire votre propre mise en œuvre de OracleBulkCopy à l'aide de la matrice de liaison.
Ici est exemple d'utilisation de projet réel:
10K enregistrements sont insérés dans 500ms!
Ici est la mise en œuvre:
REMARQUE: cette application utilise Fastmember package pour l'optimisation de l'accès aux propriétés(beaucoup plus rapide que la réflexion)