Meilleur moyen de réimporter une grande quantité de données avec un temps d'arrêt minimal

11

J'ai besoin d'importer environ 500 000 enregistrements contenant des données de recherche IP (référence en lecture seule) environ une fois par semaine (seulement trois colonnes int / bigint).

Je ne veux pas vraiment m'inquiéter de la fusion des données avec la table existante, je préfère effacer l'ancien et réimporter.

Idéalement, les requêtes exécutées sur les données continueraient de s'exécuter (nous n'en obtenons pas beaucoup et il est acceptable qu'elles s'exécutent un peu plus lentement pendant l'importation, mais doivent être en place 24 heures sur 24, 7 jours sur 7, donc exécuter ceci " hors heures "n'est pas une option).

Choses essayées jusqu'à présent

SSIS: J'ai créé un package SSIS qui tronque la table et importe - cela prend environ 30 secondes pour s'exécuter (trop long vraiment).

Table temporaire: l'importation dans une table temporaire, sa troncature et sa copie prennent également environ 30 secondes.

BCP: L'importation en masse est également plutôt trop lente (pour une raison quelconque, elle est plus lente que SSIS (même sans index à maintenir) - je suppose que c'est quelque chose à voir avec les transactions char-> int / bigint: /

Table miroir? Donc, pour le moment, je me demande comment lire le tableau dans une vue, importer les données dans un tableau miroir et modifier la vue pour pointer vers ce tableau ... cela semble être rapide, mais il semble minuscule peu hacky pour moi.

Cela semble être un problème courant, mais je ne trouve pas de pratiques recommandées - toutes les idées seraient les plus appréciées!

Merci

marque
la source

Réponses:

13

Une solution que j'ai utilisée dans le passé (et que j'ai recommandée ici et sur StackOverflow auparavant) consiste à créer deux schémas supplémentaires:

CREATE SCHEMA shadow AUTHORIZATION dbo;
CREATE SCHEMA cache  AUTHORIZATION dbo;

Créez maintenant un synoptique de votre table dans le cacheschéma:

CREATE TABLE cache.IPLookup(...columns...);

Maintenant, lorsque vous effectuez votre opération de commutation:

TRUNCATE TABLE cache.IPLookup;
BULK INSERT cache.IPLookup FROM ...;

-- the nice thing about the above is that it doesn't really
-- matter if it takes one minute or ten - you're not messing
-- with a table that anyone is using, so you aren't going to
-- interfere with active users.


-- this is a metadata operation so extremely fast - it will wait
-- for existing locks to be released, but won't block new locks
-- for very long at all:

BEGIN TRANSACTION;
  ALTER SCHEMA shadow TRANSFER    dbo.IPLookup;
  ALTER SCHEMA dbo    TRANSFER  cache.IPLookup;
COMMIT TRANSACTION;


-- now let's move the shadow table back over to
-- the cache schema so it's ready for next load:

ALTER SCHEMA cache TRANSFER shadow.IPLookup;
TRUNCATE TABLE cache.IPLookup; 

-- truncate is optional - I usually keep the data
-- around for debugging, but that's probably not
-- necessary in this case.

Ce sera plus lourd si vous avez des clés étrangères et d'autres dépendances (car vous devrez peut-être les supprimer et les recréer), et bien sûr cela invalide complètement les statistiques, etc. et cela, à son tour, peut affecter les plans, mais si le la chose la plus importante est d'obtenir des données précises devant vos utilisateurs avec une interruption minimale, cela peut être une approche à considérer.

Aaron Bertrand
la source
Merci, une autre alternative intéressante - je pense que les deux dernières déclarations ne sont pas tout à fait correctes, devraient déplacer l'ombre sur le cache et tronquer le cache. Je me demande si des synonymes pourraient également être utilisés?
Mark
Vous avez raison, je les ai mélangés. Je ne sais pas exactement comment les synonymes seraient meilleurs, je suppose que c'est aussi une approche - avoir une vue qui pointe vers un synonyme et changer le synonyme sous-jacent dans une transaction lorsque vous avez rempli l'autre version. Personnellement, je trouve cela un peu mieux - lorsque vous interrogez dbo.IPLookup, vous savez que c'est la table "actuelle" sans avoir à aller chercher la vue et le synonyme.
Aaron Bertrand
Pour info j'ai blogué à ce sujet plus en détail cette semaine: sqlperformance.com/2012/08/t-sql-queries/…
Aaron Bertrand