Performance of Inserts in Database
I just written an articel about how we can get benefit of Delayed Durability to handle large amount log activity and related locking issues
which leads to I/O condention.
You can take a look for article at here
For this we use Insert example and showed how Delayed Durability helps for improvidng perfromance.
Here I want to show some interesting fact about same Insert and how the same operation behaves differently in different scenario
and how the performance changes due to different type of handling of locks and log operation
I have use SQL Server 2014 here for testing.
Here are 3 scenarios
1. Normal Insert
Number of writes and Size is highest
Its due to write each value in log and locking maintenance for Insert
2. Insert in transaction
3. Insert in Tempdb
Number of writes and its size is more than transcation but very less compare to Normal
Its because TempDB does not have to write to transaction log and manage its related activities.
I just written an articel about how we can get benefit of Delayed Durability to handle large amount log activity and related locking issues
which leads to I/O condention.
You can take a look for article at here
For this we use Insert example and showed how Delayed Durability helps for improvidng perfromance.
Here I want to show some interesting fact about same Insert and how the same operation behaves differently in different scenario
and how the performance changes due to different type of handling of locks and log operation
I have use SQL Server 2014 here for testing.
CREATE TABLE T
(ID INT,
DATA VARCHAR(100))
Here are 3 scenarios
1. Normal Insert
DECLARE @DATE1 DATETIME
DECLARE @DATE2 DATETIME
TRUNCATE TABLE T
SELECT * INTO #BEFORE_TEST FROM
SYS.DM_IO_VIRTUAL_FILE_STATS(DB_ID('test'), NULL);
SELECT @DATE1 = GETDATE()
SET NOCOUNT ON
DECLARE @I INT =1
WHILE @I <= 100000
BEGIN
INSERT INTO T VALUES (@I, 'DATA'+ CONVERT(VARCHAR(10),@I))
SET @I = @I+1
END
SET NOCOUNT OFF
SELECT * INTO #AFTER_TEST FROM
SYS.DM_IO_VIRTUAL_FILE_STATS(DB_ID('test'), NULL);
SELECT @DATE2 = GETDATE()
SELECT DATEDIFF (SS, @DATE1,@DATE2)
SELECT
B.DATABASE_ID,
B.[FILE_ID],
CASE WHEN A.FILE_ID = 1 THEN 'LOG' ELSE 'DATA' END AS FILE_TYPE,
A.NUM_OF_READS -
B.NUM_OF_READS AS
NUM_OF_READS,
A.NUM_OF_BYTES_READ - B.NUM_OF_BYTES_READ
AS NUM_OF_BYTES_READ,
A.NUM_OF_WRITES -
B.NUM_OF_WRITES AS
NUM_OF_WRITES,
(A.NUM_OF_BYTES_WRITTEN - B.NUM_OF_BYTES_WRITTEN)/(1024.0*1024) AS
NUM_OF_BYTES_WRITTEN_MB
FROM
#BEFORE_TEST AS B
INNER JOIN
#AFTER_TEST A ON B.DATABASE_ID
= A.DATABASE_ID
AND B.[FILE_ID]
= A.[FILE_ID]
Number of writes and Size is highest
Its due to write each value in log and locking maintenance for Insert
2. Insert in transaction
DECLARE @DATE1 DATETIME
DECLARE @DATE2 DATETIME
TRUNCATE TABLE T
SELECT * INTO #BEFORE_TEST FROM
SYS.DM_IO_VIRTUAL_FILE_STATS(DB_ID('test'), NULL);
SELECT @DATE1 = GETDATE()
SET NOCOUNT ON
BEGIN TRAN
DECLARE @I INT =1
WHILE @I <= 100000
BEGIN
INSERT INTO T VALUES (@I, 'DATA'+ CONVERT(VARCHAR(10),@I))
SET @I = @I+1
END
SET NOCOUNT OFF
COMMIT TRAN
SELECT * INTO #AFTER_TEST FROM
SYS.DM_IO_VIRTUAL_FILE_STATS(DB_ID('test'), NULL);
SELECT @DATE2 = GETDATE()
SELECT DATEDIFF (SS, @DATE1,@DATE2)
SELECT
B.DATABASE_ID,
B.[FILE_ID],
CASE WHEN A.FILE_ID = 1 THEN 'LOG' ELSE 'DATA' END AS FILE_TYPE,
A.NUM_OF_READS -
B.NUM_OF_READS AS
NUM_OF_READS,
A.NUM_OF_BYTES_READ - B.NUM_OF_BYTES_READ
AS NUM_OF_BYTES_READ,
A.NUM_OF_WRITES -
B.NUM_OF_WRITES AS
NUM_OF_WRITES,
(A.NUM_OF_BYTES_WRITTEN - B.NUM_OF_BYTES_WRITTEN)/(1024.0*1024) AS
NUM_OF_BYTES_WRITTEN_MB
FROM
#BEFORE_TEST AS B
INNER JOIN
#AFTER_TEST A ON B.DATABASE_ID
= A.DATABASE_ID
AND B.[FILE_ID]
= A.[FILE_ID]
Number of writes and its size very low compare to Normal
Its due to locks are not released till transaction completes.So locking management takes lots of time and resource.
3. Insert in Tempdb
DECLARE @DATE1 DATETIME
DECLARE @DATE2 DATETIME
TRUNCATE TABLE T
SELECT * INTO #BEFORE_TEST FROM
SYS.DM_IO_VIRTUAL_FILE_STATS(DB_ID('tempdb'), NULL);
SELECT @DATE1 = GETDATE()
SET NOCOUNT ON
DECLARE @I INT =1
WHILE @I <= 100000
BEGIN
INSERT INTO T VALUES (@I, 'DATA'+ CONVERT(VARCHAR(10),@I))
SET @I = @I+1
END
SET NOCOUNT OFF
SELECT * INTO #AFTER_TEST FROM
SYS.DM_IO_VIRTUAL_FILE_STATS(DB_ID('tempdb'), NULL);
SELECT @DATE2 = GETDATE()
SELECT DATEDIFF (SS, @DATE1,@DATE2)
SELECT
B.DATABASE_ID,
B.[FILE_ID],
CASE WHEN A.FILE_ID = 1 THEN 'LOG' ELSE 'DATA' END AS FILE_TYPE,
A.NUM_OF_READS -
B.NUM_OF_READS AS
NUM_OF_READS,
A.NUM_OF_BYTES_READ - B.NUM_OF_BYTES_READ
AS NUM_OF_BYTES_READ,
A.NUM_OF_WRITES -
B.NUM_OF_WRITES AS
NUM_OF_WRITES,
(A.NUM_OF_BYTES_WRITTEN - B.NUM_OF_BYTES_WRITTEN)/(1024.0*1024) AS
NUM_OF_BYTES_WRITTEN_MB
FROM
#BEFORE_TEST AS B
INNER JOIN
#AFTER_TEST A ON B.DATABASE_ID
= A.DATABASE_ID
AND B.[FILE_ID]
= A.[FILE_ID]
Number of writes and its size is more than transcation but very less compare to Normal
Its because TempDB does not have to write to transaction log and manage its related activities.
No comments:
Post a Comment