SQL⼤批量插⼊数据性能优化--1.普通的循环⼀条条的插⼊数据,但是这样会每插⼊⼀条数据都会记录⼀条事务⽇志。
DECLARE@date DATETIME=GETDATE()
DECLARE@guid UNIQUEIDENTIFIER=NEWID()
DECLARE@session INT=@@SPID
DECLARE@time DATETIME=GETDATE()
DECLARE@ms INT
DECLARE@index INT=1
WHILE@index<=1000
BEGIN
INSERT INTO TestInsert(FAddTime,FGuid,FSession)
VALUES (@date,@guid,@session)
SET@index=@index+1;
END
SET@ms=DATEDIFF(ms,@time,GETDATE())
SELECT@ms
--2.在1的基础上加了 SET NOCOUNT ON
DECLARE@date DATETIME=GETDATE()
DECLARE@guid UNIQUEIDENTIFIER=NEWID()
DECLARE@session INT=@@SPID
DECLARE@time DATETIME=GETDATE()
DECLARE@ms INT
SET NOCOUNT ON
DECLARE@index INT=1
WHILE@index<=1000
BEGIN
INSERT INTO TestInsert(FAddTime,FGuid,FSession)
VALUES (@date,@guid,@session)
SET@index=@index+1;
END
SET@ms=DATEDIFF(ms,@time,GETDATE())
SELECT@ms
--3.在1的基础上加了事务,这样会减少事务⽇志的产⽣。
DECLARE@date DATETIME=GETDATE()
DECLARE@guid UNIQUEIDENTIFIER=NEWID()
DECLARE@session INT=@@SPID
DECLARE@time DATETIME=GETDATE()
DECLARE@ms INT
DECLARE@index INT=1
BEGIN TRAN
WHILE@index<=1000
BEGIN
INSERT INTO TestInsert(FAddTime,FGuid,FSession)
VALUES (@date,@guid,@session)
SET@index=@index+1;
END
COMMIT TRAN
SET@ms=DATEDIFF(ms,@time,GETDATE())
SELECT@ms
--4.在3的基础上加了 SET NOCOUNT ON
DECLARE@date DATETIME=GETDATE()
DECLARE@guid UNIQUEIDENTIFIER=NEWID()
DECLARE@session INT=@@SPID
DECLARE@time DATETIME=GETDATE() DECLARE@ms INT
DECLARE@index INT=1
SET NOCOUNT ON
BEGIN TRAN
WHILE@index<=1000
BEGIN
INSERT INTO TestInsert(FAddTime,FGuid,FSession) VALUES (@date,@guid,@session)
SET@index=@index+1;
END
COMMIT TRAN
SET@ms=DATEDIFF(ms,@time,GETDATE()) SELECT@ms
--5.使⽤CTE批量插⼊数据
批量更新sql语句DECLARE@date DATETIME=GETDATE() DECLARE@guid UNIQUEIDENTIFIER=NEWID() DECLARE@session INT=@@SPID
DECLARE@time DATETIME=GETDATE() DECLARE@ms INT
;WITH cte(FAddTime,FGuid,FSession)
AS
(
SELECT FAddTime,FGuid,FSession
FROM TestInsert
WHERE FID<=1000
)
INSERT INTO TestInsert(FAddTime,FGuid,FSession) SELECT FAddTime,FGuid,FSession FROM cte
SET@ms=DATEDIFF(ms,@time,GETDATE()) SELECT@ms
--6.在5的基础上加上了 SET NOCOUNT ON DECLARE@date DATETIME=GETDATE() DECLARE@guid UNIQUEIDENTIFIER=NEWID() DECLARE@session INT=@@SPID
DECLARE@time DATETIME=GETDATE() DECLARE@ms INT
SET NOCOUNT ON
;WITH cte(FAddTime,FGuid,FSession)
AS
(
SELECT FAddTime,FGuid,FSession
FROM TestInsert
WHERE FID<=1000
)
INSERT INTO TestInsert(FAddTime,FGuid,FSession) SELECT FAddTime,FGuid,FSession FROM cte
SET@ms=DATEDIFF(ms,@time,GETDATE()) SELECT@ms
--7.直接使⽤ INSERT INTO SELECT 语句批量插⼊数据DECLARE@date DATETIME=GETDATE() DECLARE@guid UNIQUEIDENTIFIER=NEWID() DECLARE@session INT=@@SPID
DECLARE@time DATETIME=GETDATE() DECLARE@ms INT
INSERT INTO TestInsert(FAddTime,FGuid,FSession)
SELECT FAddTime,FGuid,FSession
FROM TestInsert
WHERE FID<=1000
SET@ms=DATEDIFF(ms,@time,GETDATE())
SELECT@ms
--8.在7的基础上加上了 SET NOCOUNT ON
DECLARE@date DATETIME=GETDATE()
DECLARE@guid UNIQUEIDENTIFIER=NEWID()
DECLARE@session INT=@@SPID
DECLARE@time DATETIME=GETDATE()
DECLARE@ms INT
SET NOCOUNT ON
INSERT INTO TestInsert(FAddTime,FGuid,FSession)
SELECT FAddTime,FGuid,FSession
FROM TestInsert
WHERE FID<=1000
SET@ms=DATEDIFF(ms,@time,GETDATE())
SELECT@ms
总结:
在批量插⼊数据时,要记得加上 SET NOCOUNT ON。并尽可能加上 BEGIN TRAN。
当然,最好使⽤ CTE,这可能会带来性能上的巨⼤提升。
SET ONCOUNT ON作⽤:阻⽌在结果集中返回显⽰受T-SQL语句或则usp影响的⾏计数信息。
当SET ONCOUNT ON时候,不返回计数,
当SET NOCOUNT OFF时候,返回计数。
@@ROWCOUNT函数将更新,即使在 SET NOCOUNT ON。
当 SET NOCOUNT 为 ON 时,将不向客户端发送存储过程中每个语句的 DONE_IN_PROC 消息。
如果存储过程中包含⼀些并不返回许多实际数据的语句,或者如果过程包含 Transact-SQL 循环,⽹络通信流量便会⼤量减少,因此,将 SET NOCOUNT 设置为 ON 可显著提⾼性能。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。