Pourquoi "Select * into targettable from sourcetable" est plus rapide que "insert in targettable select * from sourcetable"

9

Ce titre est la question. Je suis curieux de connaître la réponse. Quelqu'un a dit

sélectionner dans est connecté de manière minimale dans la base de données du modèle de récupération simple ... Je n'y suis pas allé du tout.

Extrait de Microsoft:

La quantité de journalisation pour SELECT ... INTO dépend du modèle de récupération en vigueur pour la base de données. Sous le modèle de récupération simple ou le modèle de récupération enregistré en bloc, les opérations en bloc sont enregistrées de manière minimale. Avec une journalisation minimale, l'utilisation de l'instruction SELECT… INTO peut être plus efficace que la création d'une table, puis le remplissage de la table avec une instruction INSERT

Cherche de l'aide

Merci


la source
Quelle base de données utilisez-vous? Quelles structures sont les tables? Comment avez-vous mesuré que l'un est plus rapide que l'autre?
Je serais surpris s'il y avait une différence sur un SGBD bien écrit.
Base de données: Sql server 20005 ... et j'ai entendu cela .. même je ne suis pas sûr à 100% ... Je cherche ce que disent les autres .. Comme j'ai mentionné que quelqu'un me l'a dit ..
Trouvé un lien qui confirme qu'il SELECT INTOpeut être enregistré de manière minimale lorsque vous n'utilisez pas la récupération complète.
Damien_The_Unbeliever

Réponses:

10

Quelques idées / théories:

SELECT INTO ... permet au SGBDR de déterminer l'ordre de tri en fonction de l'ordre de votre table d'origine. Si vous insérez dans une table existante, un tri peut être nécessaire pour faire correspondre un ou des index cluster (s) ou non cluster (s).

Aucun index - lorsque SELECT INTO...le SGBDR sait avec certitude qu'il n'y a aucun index préexistant à mettre à jour.

Pas de conflit - puisque la table dans laquelle vous insérez n'existe pas, SQL Server n'a pas à se soucier du verrouillage au niveau des lignes ou de la gestion des conflits. Rien d'autre ne peut référencer la table que vous créez car elle n'existe pas.

Cela étant dit, il existe d'autres façons de s'insérer dans un tableau très rapidement.

  • Assurez-vous que vos clés d'index en cluster correspondent lorsque cela est possible. Cela signifie qu'il n'y a pas de tri à la volée

  • Désactivez tous les index non groupés. Explicite.

  • Réglez le mode de récupération sur simple et tracez l'indicateur 610 sur ON. Utilisez le TABLOCKconseil sur votre table cible et le NOLOCKconseil sur votre table source.

Par exemple, supposons que tablea et tableb ont le même index clusterisé:

INSERT INTO TableB WITH (TABLOCK)
SELECT <Columns>
FROM TableA WITH (NOLOCK)

D'après mon expérience, cela est plus rapide que d'utiliser SELECT INTO...et de créer ensuite l'index clusterisé. Veuillez noter que cela peut également fonctionner sur une table qui contient déjà des données, ce qui est un scénario beaucoup plus utile.

ÉDITER:

Voici un livre blanc fantastiquement détaillé de MS pour les performances de chargement des données dans Sql Server 2008.

JNK
la source
3
Réponse très approfondie JNK. En outre, lorsqu'il est correctement mis en œuvre et que le modèle de récupération n'est pas complet, une tâche de flux de données SSIS simple peut être plus rapide que l'une ou l'autre. Pourquoi? Les deux ci-dessus émettront un verrou exclusif (la lecture est multi-thread mais l'écriture est single thread). Tant qu'un verrou de table est utilisé avec l'adaptateur de destination, SSIS utilisera un verrou de mise à jour en bloc (la lecture et l'écriture sont multi-thread).
brian