Il y a deux solutions à ce problème. Vous pourriez essayer d'être intelligent et de ne transférer que les changements - mais cela nécessite une certaine intégration sur la base de données source ; je suis sûr que votre administrateur de base de données peut vous aider avec cela - potentiellement des déclencheurs qui gardent la trace de toutes les lignes touchées (par exemple en utilisant la clé primaire de la table source). Cette solution s'adapte assez bien, mais elle est plus compliquée. Je pense que vous devriez envisager une deuxième option : la force brute simple.
D'après ce que j'ai entendu, votre table entière tient confortablement dans 100MB. Ce n'est tout simplement pas beaucoup de données. En supposant que vous puissiez obtenir un taux de transfert de 10 Mo/s (ce qui n'est pas du tout exagéré), vous pourriez tout transférer en seulement 10 secondes. Si, comme vous le dites, vous n'avez besoin que de quelques colonnes, le transfert de données total pourrait être considérablement inférieur. En partant du chiffre de 10 secondes toutes les cinq minutes, cela représenterait une charge de l'ordre de 3% pour maintenir les données à jour - et il s'agit d'une requête triviale pour la base de données source qui ne causera probablement pas beaucoup de charge, d'autant plus que tout sera mis en cache en mémoire puisque l'ensemble de données est si petit.
Jetez un coup d'œil à SqlBulkCopy
. Cet article ( Transférer les données en utilisant SqlBulkCopy
) est un exemple de son utilisation pour copier des données d'une base de données à une autre. Le lecteur de données source peut être n'importe quoi ; je l'utilise pour insérer des données calculées à partir d'objets, par exemple, mais un cas particulièrement facile est un DbDataReader, que vous pouvez obtenir pour l'instruction select de Postgresql.
Malheureusement, les options par défaut ne sont pas très brillantes, donc vous voudrez probablement spécifier SqlBulkCopyOptions
utile pour vous. TableLock n'est probablement pas un mauvais choix. De plus, si vous faites cela en parallèle (c'est-à-dire plusieurs insertions en masse dans une table), faites attention aux index (qui peuvent provoquer des blocages). Si vous jouez avec la taille du lot de copies en masse, vous pouvez optimiser le compromis entre le débit et l'utilisation de la mémoire, bien que la valeur par défaut puisse fonctionner parfaitement.
Conceptuellement, je ferais ça :
- Ouvrez une connexion à vos bases de données source et cible (utilisez la fonction
using
)
- commencer un
SqlTransaction
sur la connexion de la base de données cible
- supprimer toutes les lignes de la table cible.
- copie en masse de la source vers la cible (n'oubliez pas de passer la transaction)
- commettre
De cette façon, vous mettrez à jour de façon atomique la table de destination.
Je ne suis pas sûr de ce que vous essayez de faire, mais s'il s'agit d'une forme de mise en cache, envisagez de supprimer complètement le serveur SQL cible et de laisser les données en mémoire sous forme de tableau d'objets. Les accès en mémoire aux données en lecture seule sont très rapides et votre ensemble de données tient facilement en mémoire.