INSERT INTO vs SELECT INTO

127

Quelle est la différence entre l'utilisation

SELECT ... INTO MyTable FROM...

et

INSERT INTO MyTable (...)
SELECT ... FROM ....

?

De BOL [ INSERT , SELECT ... INTO ], je sais que l'utilisation de SELECT ... INTO créera la table d'insertion sur le groupe de fichiers par défaut s'il n'existe pas déjà, et que la journalisation de cette instruction dépend de la récupération modèle de la base de données.

  1. Quelle déclaration est préférable?
  2. Y a-t-il d'autres implications sur les performances?
  3. Quel est un bon cas d'utilisation de SELECT ... INTO sur INSERT INTO ...?

Edit: J'ai déjà déclaré que je sais que ce SELECT INTO ... crée une table là où elle n'existe pas. Ce que je veux savoir, c'est que SQL inclut cette instruction pour une raison, qu'est-ce que c'est? Est-ce qu'il fait quelque chose de différent dans les coulisses pour insérer des lignes, ou est-ce juste du sucre syntaxique au-dessus d'un CREATE TABLEet INSERT INTO.

jowenece
la source
Un petit facteur: INSERT INTOa deux mots clés (select & into) à l'avant qui permettent au monde de savoir qu'il ne s'agit pas d'une instruction SQL ordinaire, alors qu'elle SELECT ... INTOcommence, au moins, à ressembler à une instruction SQL ordinaire. Une petite raison de privilégier le premier.
Martin F

Réponses:

122
  1. Ils font des choses différentes. À utiliser INSERTlorsque la table existe. À utiliser SELECT INTOquand ce n'est pas le cas.

  2. Oui. INSERTsans indication de table est normalement consigné. SELECT INTOest minimalement consigné en supposant que les indicateurs de trace appropriés sont définis.

  3. D'après mon expérience, il SELECT INTOest le plus couramment utilisé avec des ensembles de données intermédiaires, tels que des #temptables, ou pour copier une table entière comme pour une sauvegarde. INSERT INTOest utilisé lorsque vous insérez dans une table existante avec une structure connue.

ÉDITER

Pour répondre à votre modification, ils font des choses différentes. Si vous créez un tableau et que vous souhaitez définir la structure, utilisez CREATE TABLEet INSERT. Exemple de problème pouvant être créé: vous avez une petite table avec un champ varchar. La plus grande chaîne de votre table est désormais de 12 octets. Votre ensemble de données réel nécessitera jusqu'à 200 octets. Si vous faites à SELECT INTOpartir de votre petite table pour en créer une nouvelle, la dernière INSERTéchouera avec une erreur de troncature car vos champs sont trop petits.

JNK
la source
4
Mes deux cents, je pense qu'introduire l'échec est une bonne chose. Je veux savoir si mes données ne correspondent pas à mon format / taille de données attendu. J'essaie toujours de définir ma table en utilisant CREATE TABLEet ensuite INSERT INTO, il est plus facile de tester l' SELECTinstruction par elle-même, sans exécuter l'insertion.
Doug Chamberlain
1
@Doug - Je suis d'accord. J'utilise presque exclusivement SELECT INTOpour créer une table temporaire ou pour faire une sauvegarde rapide d'une table existante avec laquelle je vais faire un singe.
JNK
1
@JNK - À partir de BOL, SELECT INTO crée une table avec une structure basée sur les types de données des colonnes de la liste de sélection. Donc, dans votre exemple, vous pouvez rectifier la situation en convertissant explicitement le varchar à une taille suffisante. Correct?
jowenece
2
@Jowenece - oui je m'y attend. Si je vais à ce problème, je vais continuer et utiliser une CREATEdéclaration cependant.
JNK
24
  1. Quelle déclaration est préférable? Cela dépend de ce que vous faites.

  2. Y a-t-il d'autres implications sur les performances? Si la table est une table permanente, vous pouvez créer des index au moment de la création de la table, ce qui a des implications négatives et positives sur les performances. Select into ne recrée pas les index qui existent sur les tables actuelles et, par conséquent, l'utilisation ultérieure de la table peut être plus lente que nécessaire.

  3. Quel est un bon cas d'utilisation de SELECT ... INTO sur INSERT INTO ...? Sélectionner dans est utilisé si vous ne connaissez pas la structure du tableau à l'avance. Il est plus rapide d'écrire que de créer une table et une instruction d'insertion, il est donc parfois utilisé pour accélérer le développement. Il est souvent plus rapide à utiliser lorsque vous créez une table temporaire rapide pour tester des éléments ou une table de sauvegarde d'une requête spécifique (peut-être des enregistrements que vous allez supprimer). Il devrait être rare de le voir utilisé dans du code de production qui s'exécutera plusieurs fois (sauf pour les tables temporaires) car il échouera si la table existait déjà.

Il est parfois utilisé de manière inappropriée par des personnes qui ne savent pas ce qu'elles font. Et ils peuvent causer des ravages dans la base de données. Je pense fortement qu'il est inapproprié d'utiliser SELECT INTO pour autre chose qu'une table jetable (une sauvegarde temporaire, une table temporaire qui disparaîtra à la fin du processus stocké, etc.). Les tables permanentes nécessitent une réflexion approfondie quant à leur conception et SELECT INTO permet d'éviter de penser à quelque chose d'aussi basique que les colonnes et les types de données.

En général, je préfère l'utilisation de l'instruction create table et insert - vous avez plus de contrôles et c'est mieux pour les processus répétables. En outre, si la table est une table permanente, elle doit être créée à partir d'un script de création de table distinct (celui qui est dans le contrôle de code source) car la création d'objets permanents ne devrait pas, en général, dans le code être des insertions / suppressions / mises à jour ou des sélections à partir d'un table. Les modifications d'objets doivent être traitées séparément des modifications de données, car les objets ont des implications au-delà des besoins d'une insertion / mise à jour / sélection / suppression spécifique. Vous devez considérer les meilleurs types de données, penser aux contraintes FK, PK et autres contraintes, prendre en compte les exigences d'audit, penser à l'indexation, etc.

HLGEM
la source
5

La principale différence est que SELECT INTO MyTable créera une nouvelle table appelée MyTable avec les résultats, tandis que INSERT INTO requiert que MyTable existe déjà.

Vous n'utiliseriez SELECT INTO que dans le cas où la table n'existait pas et que vous souhaitiez la créer en fonction des résultats de votre requête. En tant que tels, ces deux déclarations ne sont vraiment pas comparables. Ils font des choses très différentes.

En général, SELECT INTO est utilisé plus souvent pour des tâches ponctuelles, tandis que INSERT INTO est utilisé régulièrement pour ajouter des lignes aux tables.

EDIT:
Bien que vous puissiez utiliser CREATE TABLE et INSERT INTO pour accomplir ce que SELECT INTO fait, avec SELECT INTO vous n'avez pas besoin de connaître la définition de la table au préalable. SELECT INTO est probablement inclus dans SQL car il facilite beaucoup les tâches telles que la création de rapports ad hoc ou la copie de tables.

rsbarro
la source
CREATE TABLE et SELECT INTO sont à peu près la même chose (vous n'avez pas besoin de INSERT INTO comme ajout pour accomplir ce que SELECT INTO fait) et SELECT INTO n'est pas recommandé, je pense. Voir dba.stackexchange.com/questions/156105/… .
Rick
4

Chaque instruction a un cas d'utilisation distinct. Ils ne sont pas interchangeables.

SELECT...INTO MyTable...crée un nouveau MyTablelà où il n'en existait pas auparavant.

INSERT INTO MyTable...SELECT...est utilisé lorsqu'il MyTableexiste déjà.

Joe Stefanelli
la source
4
Vous n'avez répondu à aucune de mes questions et j'ai déjà indiqué votre réponse.
jowenece
5
Les réponses à vos questions sont implicites. Pour être plus clair, il n'y a pas de déclaration "préférable" car chacun a un cas d'utilisation distinct. Les déclarations ne sont pas interchangeables. Utilisez la première version lorsque vous souhaitez créer une nouvelle table qui n'existe pas. Utilisez la deuxième version lorsque la table existe déjà.
Joe Stefanelli
2
Pourquoi voudrais-je faire cela par rapport à la création d'une table temporaire, puis à l'insérer? Y a-t-il un avantage?
jowenece
4

En fait SELECT ... INTO crée non seulement la table, mais échouera si elle existe déjà, donc fondamentalement, la seule fois où vous l'utiliserez est lorsque la table dans laquelle vous insérez n'existe pas.

En ce qui concerne votre EDIT:

Personnellement, j'utilise principalement SELECT ... INTO lorsque je crée une table temporaire. C'est pour moi la principale utilisation. Cependant, je l'utilise également lors de la création de nouvelles tables avec de nombreuses colonnes avec des structures similaires à celles d'autres tables, puis je les modifie afin de gagner du temps.

AJC
la source
1
Je vois principalement des utilisations de SELECT..INTO pour les tables temporaires, mais y a-t-il une raison de préférer cela à la création d'une table temporaire avec une instruction CREATE TABLE? Par exemple - gain de performance?
jowenece
3
@jowenece Je pense principalement pour la simplicité ... Disons également que vous avez une requête dynamique. Si vous ne connaissez pas la structure, vous ne pouvez pas créer la table avant la main, et il est beaucoup plus facile d'utiliser SELECT ... INTO que de créer une table de manière dynamique.
AJC
3

SELECT INTO est généralement utilisé pour générer des tables temporaires ou pour copier une autre table (données et / ou structure).

Dans le code au jour le jour, vous utilisez INSERT car vos tables doivent déjà exister pour être lues, UPDATEd, DELETEd, JOINed etc. Remarque: le mot clé INTO est facultatif avec INSERT

Autrement dit, les applications ne créeront et ne supprimeront normalement pas de tables dans le cadre d'opérations normales, sauf s'il s'agit d'une table temporaire pour une utilisation limitée et spécifique.

Une table créée par SELECT INTO n'aura pas de clés, d'index ou de contraintes contrairement à une table réelle, persistante et déjà existante

Les 2 ne sont pas directement comparables car ils n'ont presque aucun chevauchement d'utilisation

gbn
la source
2

Je veux seulement aborder le deuxième point de la question qui a trait à la performance, car aucune autre instance ne l'a couvert. Select Into est beaucoup plus rapide que l'insertion dans, lorsqu'il s'agit de tables avec de grands ensembles de données. Je préfère choisir dans quand je dois lire un très grand tableau. insérer dans pour une table avec 10 millions de lignes peut prendre des heures tandis que select into le fera en quelques minutes, et quant à la perte d'index sur une nouvelle table, vous pouvez recréer les index par requête et pouvez encore gagner beaucoup plus de temps par rapport à insérer dans.

Niraj
la source
C'est vrai, mais c'est principalement parce que SQL Server sait qu'il n'y a pas de conflit pour la table de destination. La performance de insert into #temp with(tablock) select * from ..est à peu près la même que celle deselect * into #temp from ...
Brian
1

Sélectionnez dans crée une nouvelle table pour vous à ce moment-là, puis insérez-y des enregistrements à partir de la table source. La table nouvellement créée a la même structure que la table source.Si vous essayez d'utiliser select into pour une table existante, cela produira une erreur, car il essaiera de créer une nouvelle table avec le même nom. Insérer dans nécessite que la table existe dans votre base de données avant d'y insérer des lignes.

Satish Vishwakarma
la source
1

La simple différence entre sélectionner dans et insérer dans est: -> Sélectionner dans n'a pas besoin de table existante. Si vous voulez copier les données de la table A, il vous suffit de taper Select * INTO [tablename] from A. Ici, tablename peut être une table existante ou une nouvelle table sera créée qui a la même structure que la table A.

-> Insérer dans nécessite une table existante.INSERT INTO [nomtable] SELECT * FROM A ;. Ici, nom_table est une table existante.

Select Into est généralement plus populaire pour copier des données, en particulier les données de sauvegarde.

Vous pouvez utiliser selon vos besoins, c'est totalement le choix du développeur qui doit être utilisé dans son scénario.

En termes de performances, Insert INTO est rapide.

Références :

https://www.w3schools.com/sql/sql_insert_into_select.asp https://www.w3schools.com/sql/sql_select_into.asp

Aditya Parmar
la source
-2

Sélectionner dans pour les grands ensembles de données peut ne convenir qu'à un seul utilisateur utilisant une seule connexion à la base de données effectuant une tâche d'opération en bloc. Je ne recommande pas d'utiliser

SELECT * INTO table

car cela crée une grosse transaction et crée un verrou de schéma pour créer l'objet, empêchant les autres utilisateurs de créer un objet ou d'accéder aux objets système jusqu'à la fin de l' SELECT INTOopération.

Comme preuve de concept, ouvrez 2 sessions, dans la première session essayez d'utiliser

select into temp table from a huge table 

et dans la deuxième section, essayez de

create a temp table 

et vérifiez les verrous, le blocage et la durée de la deuxième session pour créer un objet de table temporaire. Ma recommandation est toujours une bonne pratique de créer et d'insérer une instruction et, si nécessaire, pour une journalisation minimale, utilisez l'indicateur de trace 610.

user6802184
la source