首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

INSERT INTO SELECT vs SELECT INTO 差異全解析:資料複製、建表、權限、日誌、效能

     編輯:關於SqlServer

核心差異速查

特性INSERT INTO ... SELECTSELECT ... INTO
目標表必須預先存在自動建立
結構來源目標表定義查詢結果投影
權限需求目標表 INSERT 權限建表權限 (CREATE TABLE)
索引/約束/觸發器保留目標表原有不複製 (僅資料+欄位定義)
身分識別欄需 SET IDENTITY_INSERT ON自動保留 IDENTITY 屬性
日誌記錄完整記錄 (可最小化)最小日誌 (Bulk Logged/Simple 模式下)
並行度可指定 TABLOCK 並行串行 (舊版),2014+ 支援並行
事務行為可回滾可回滾 (但 DDL 隱式提交風險)

語法範例

-- INSERT INTO SELECT:目標表 t2 已存在
INSERT INTO t2 (id, name, pwd)
SELECT id, name, pwd FROM t1;

-- SELECT INTO:自動建立 t2
SELECT id, name, pwd INTO t2 FROM t1;
-- 等價於:
-- CREATE TABLE t2 (id ..., name ..., pwd ...);
-- INSERT INTO t2 SELECT id, name, pwd FROM t1;

效能與日誌深度解析

  • SELECT INTO:BULK LOGGED/SIMPLE 復原模式下最小日誌,僅記錄頁配置,速度極快,適合大量資料初始化、備份、ETL 階段表
  • INSERT INTO SELECT:預設完整日誌;加 WITH (TABLOCK) + BULK LOGGED 可達最小日誌並行插入
  • 大資料量 (>100 萬) 首選 SELECT INTO 建暫存表,再 INSERT INTO ... SELECT 寫正式表 (保留索引/約束)

常見陷阱

  1. SELECT INTO 鎖定系統表 (sysobjects/syscolumns) 較久,高併發下易阻塞 → 避免核心業務高峰期執行
  2. 目標表有計算欄、預設值、觸發器 → SELECT INTO 會丟失,必須用 INSERT INTO SELECT
  3. 身分識別欄種子值:SELECT INTO 保留種子,INSERT INTO 需手動 DBCC CHECKIDENT 重置

最佳實踐建議

資料量 < 10 萬、需保留索引約束 → INSERT INTO SELECT
資料量 > 100 萬、臨時表/階段表、無約束 → SELECT INTO (最小日誌)
大量寫入正式表、需保留結構 → 
  1. SELECT INTO #stage FROM source (最小日誌、極速)
  2. CREATE INDEX ON #stage ... (可選)
  3. INSERT INTO target WITH (TABLOCK) SELECT ... FROM #stage (最小日誌並行)
  4. DROP TABLE #stage
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved