INSERT INTO vs SELECT INTO


127

使用の違いは何ですか

SELECT ... INTO MyTable FROM...

そして

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

BOL [ INSERTSELECT ... INTO ]から、SELECT ... INTOを使用すると、デフォルトのファイルグループに挿入テーブルまだ存在しない場合は作成され、このステートメントのロギングはリカバリに依存することがわかりますデータベースのモデル。

  1. どちらのステートメントが望ましいですか?
  2. 他のパフォーマンスへの影響はありますか?
  3. INSERT INTO ...よりもSELECT ... INTOの良いユースケースは何ですか?

編集:私はすでに、そのSELECT INTO ...が存在しないテーブルを作成することを知っていると述べました。私が知りたいのは、SQLに理由のためにこのステートメントが含まれているということです。それは何ですか?それは、行を挿入するために舞台裏で何か別のをやっている、またはそれはAの上だけ糖衣構文であるCREATE TABLEINSERT INTO


1つの小さな要素:INSERT INTO2つのキーワード(select&into)がすぐ前にあり、これが通常のSQLステートメントではないことを世界に知らせますSELECT ... INTOが、少なくとも通常のSQLステートメントのように見えます。前者を支持する小さな理由。
マーティンF

回答:


121
  1. 彼らは異なることをします。INSERTテーブルが存在する場合に使用します。使用SELECT INTOしない場合に使用してください。

  2. はい。 INSERT通常、テーブルヒントがない場合はログに記録されます。 SELECT INTO適切なトレースフラグが設定されていると想定して、最小限のログが記録されます。

  3. 私の経験でSELECT INTOは、#tempテーブルなどの中間データセットで、またはバックアップのようにテーブル全体をコピーするために最もよく使用されます。 INSERT INTO既知の構造を持つ既存のテーブルに挿入するときに使用されます。

編集

あなたの編集に対処するために、彼らは異なることをします。テーブルを作成していて、構造体を定義する場合はCREATE TABLE、およびを使用しINSERTます。作成可能な問題の例:varcharフィールドを持つ小さなテーブルがあります。テーブルの最大文字列は12バイトです。実際のデータセットには最大200バイトが必要です。その場合はSELECT INTO新しいものを作るためにあなたの小さなテーブルから、後には、INSERTあなたのフィールドが小さすぎるので、切り捨てエラーで失敗します。


4
私の2セントは、失敗を導入することは良いことだと思います。データが予想されるデータ形式/サイズと一致しないかどうかを知りたい。常にテーブルを使用CREATE TABLEしてテーブルを定義しようとしています。INSERT INTOまた、SELECT挿入を実行せずにステートメントを単独でテストする方が簡単です。
Doug Chamberlain

1
@ダグ-同意する。SELECT INTO一時的に使用するのは、一時テーブルの作成、またはサルで使用する既存のテーブルのクイックバックアップです。
JNK、2011

1
@JNK-BOLから、SELECT INTOは、選択リスト内の列のデータ型に基づいた構造を持つテーブルを作成します。したがって、例では、varcharを十分なサイズに明示的にキャストすることで状況を修正できます。正しい?
jowenece 2011

2
@Jowenece-はい、そう思います。その問題が発生した場合は、先に進んでCREATEステートメントを使用します。
JNK、2011

23
  1. どちらのステートメントが望ましいですか? 何をしているかによります。

  2. 他のパフォーマンスへの影響はありますか?テーブルが永続テーブルである場合は、テーブル作成時にインデックスを作成できます。これは、パフォーマンスに悪影響を及ぼす可能性があります。select intoは、現在のテーブルに存在するインデックスを再作成しないため、その後のテーブルの使用は必要以上に遅くなる可能性があります。

  3. INSERT INTO ...よりもSELECT ... INTOの良いユースケースは何ですか?事前にテーブル構造がわからない場合は、select intoを使用します。create tableやinsertステートメントよりも書く方が速いので、時々開発をスピードアップするために使用されます。クイック一時テーブルを作成して特定のクエリのバックアップテーブルまたは特定のクエリ(削除するレコードなど)をテストする場合は、多くの場合より高速です。テーブルが既に存在していると失敗するため、(一時テーブルを除いて)複数回実行される本番コードで使用されることはまれです。

何をしているのか分からない人が不適切に使用することがあります。そしてそれらは結果としてデータベースに大混乱を引き起こす可能性があります。使い捨てテーブル(一時バックアップ、ストアドプロシージャの最後に消える一時テーブルなど)以外にSELECT INTOを使用することは不適切だと強く感じます。パーマネントテーブルでは、設計について真の考えが必要です。SELECTINTOを使用すると、どの列やどのデータ型など、基本的なことについても簡単に考えることができます。

一般的に、私はcreate tableとinsertステートメントの使用を好みます-より多くのコントロールがあり、繰り返し可能なプロセスに適しています。さらに、テーブルが永続的なテーブルである場合、永続的なオブジェクトを作成することは一般にコードでは挿入/削除/更新またはテーブル。オブジェクトには特定の挿入/更新/選択/削除の必要性を超える影響があるため、オブジェクトの変更はデータの変更とは別に処理する必要があります。最適なデータ型を検討し、FK制約、PKおよびその他の制約を検討し、監査要件を検討し、索引付けを検討する必要があります。


5

主な違いは、SELECT INTO MyTableではMyTableと呼ばれる新しいテーブルが結果とともに作成されるのに対し、INSERT INTOではMyTableがすでに存在している必要があることです。

SELECT INTOは、テーブルが存在せず、クエリの結果に基づいて作成したい場合にのみ使用します。そのため、これら2つのステートメントは実際には比較できません。彼らは非常に異なることをします。

一般に、SELECT INTOは1回限りのタスクで頻繁に使用されますが、INSERT INTOはテーブルに行を追加するために定期的に使用されます。

編集:
CREATE TABLEとINSERT INTOを使用してSELECT INTOの機能を実行できますが、SELECT INTOを使用すると、事前にテーブル定義を知っている必要はありません。SELECT INTOは、アドホックレポートやテーブルのコピーなどのタスクをはるかに簡単にするため、SQLに含まれている可能性があります。


CREATE TABLEとSELECT INTOはほぼ同じものであり(SELECT INTOの機能を実現するためにINSERT INTOを追加する必要はありません)、SELECT INTOはお勧めしません。dba.stackexchange.com/questions/156105/…を参照してください。
リック

4

各ステートメントには、異なるユースケースがあります。互換性はありません。

SELECT...INTO MyTable...MyTable以前に存在しなかった場所に新しいものを作成します。

INSERT INTO MyTable...SELECT...MyTableすでに存在する場合に使用されます。


4
あなたは私の質問のどれにも答えませんでした、そして私はあなたの答えをすでに述べました。
jowenece 2011

5
あなたの質問に対する答えは暗示されています。明確にするために、それぞれに明確なユースケースがあるため、「好ましい」ステートメントはありません。ステートメントは互換性がありません。存在しない新しいテーブルを作成する場合は、最初のバージョンを使用します。テーブルがすでに存在する場合は、2番目のバージョンを使用します。
Joe Stefanelli、2011

2
なぜ一時テーブルを作成してから挿入するのですか?メリットはありますか?
jowenece 2011

4

実際にSELECT ... INTOはテーブルを作成するだけでなく、テーブルが既に存在する場合は失敗するため、基本的に使用するのは挿入先のテーブルが存在しない場合のみです。

あなたの編集に関して:

個人的には、一時テーブルを作成するときに主にSELECT ... INTOを使用します。それが私にとっての主な用途です。ただし、他のテーブルと同様の構造を持つ多くの列を持つ新しいテーブルを作成するときにも使用し、時間を節約するために編集します。


1
主に一時テーブルでのSELECT..INTOの使用も見ていますが、CREATE TABLEステートメントで一時テーブルを作成するよりも優先する理由はありますか?例-パフォーマンスの向上?
jowenece 2011

3
@jowenece主に単純にするために考えます...また、動的クエリがあるとします。構造がわからないので、事前にテーブルを作成することはできません。テーブルを動的に作成するよりもSELECT ... INTOを使用する方がはるかに簡単です。
AJC 2011

3

SELECT INTOは通常、一時テーブルを生成したり、別のテーブル(データや構造)をコピーしたりするために使用されます。

毎日のコードでは、テーブルの読み取り、更新、削除、結合などがすでに存在している必要があるため、INSERTを使用します。注:INTOキーワードは、INSERTではオプションです

つまり、アプリケーションは、スコープが限定された特定の使用法のための一時テーブルでない限り、通常の操作の一部としてテーブルを作成および削除しません。

SELECT INTOによって作成されたテーブルには、実際の永続化された既存のテーブルとは異なり、キー、インデックス、または制約はありません。

2つは、使用法の重複がほとんどないため、直接比較できません。


2

パフォーマンスに関連する質問の2番目の点のみを取り上げたいと思います。これをカバーしている組織は他にないからです。Select Intoは、大きなデータセットを含むテーブルに関しては、insert intoよりもはるかに高速です。非常に大きなテーブルを読み取る必要がある場合は、select intoを選択します。1,000万行のテーブルのinsert intoは数時間かかる場合がありますが、select intoはこれを数分で実行します。新しいテーブルのインデックスを失うことに関しては、クエリでインデックスを再作成でき、それよりもはるかに多くの時間を節約できます。に挿入します。


それは本当ですが、それは主にSQL Serverが宛先テーブルの競合がないことを知っているためです。パフォーマンスは、insert into #temp with(tablock) select * from ..おおよそのパフォーマンスと同じであるselect * into #temp from ...
ブライアン

1

その時点で新しいテーブルを選択して作成し、ソーステーブルからレコードを挿入します。新しく作成されたテーブルの構造はソーステーブルと同じです。既存のテーブルに対してselect intoを使用しようとすると、同じ名前で新しいテーブルを作成しようとするため、エラーが発生します。Insert intoでは、テーブルに行を挿入する前に、データベースにテーブルが存在している必要があります。


1

Select IntoとInsert Intoの単純な違いは次のとおりです。-> Select Intoは既存のテーブルを必要としません。テーブルAのデータをコピーする場合は、Select * INTO [tablename] from Aと入力します。ここで、tablenameは既存のテーブルにすることも、テーブルAと同じ構造を持つ新しいテーブルを作成することもできます。

->既存のテーブルが必要です。INSERTINTO [テーブル名] SELECT * FROM A ;. ここでtablenameは既存のテーブルです。

Select Intoは、通常、データ、特にバックアップデータをコピーするのに一般的です。

あなたはあなたの要件に従って使用することができます、それは彼のシナリオで使用されるべき完全に開発者の選択です。

Insert INTOのパフォーマンスは、高速です。

参照:

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


-2

大規模なデータセットのselect intoは、一括操作タスクを実行するデータベースへの単一の接続を使用する単一のユーザーにのみ適している場合があります。使用はお勧めしません

SELECT * INTO table

これにより、1つの大きなトランザクションが作成され、オブジェクトを作成するためのスキーマロックが作成され、SELECT INTO操作が完了するまで他のユーザーがオブジェクトを作成したりシステムオブジェクトにアクセスしたりできなくなります。

概念実証として2つのセッションを開き、最初のセッションで使用してみます

select into temp table from a huge table 

そして2番目のセクションで

create a temp table 

ロック、ブロッキング、2番目のセッションの継続時間を確認して、一時テーブルオブジェクトを作成します。ステートメントを作成して挿入することは常に良い習慣であり、最小限のロギングが必要な場合はトレースフラグ610を使用することをお勧めします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.