Hi.
I have real problem with getting right "Write time" statistics.
I'm trying 2 different approaches:
1. base on dm_io_virtual_file_stats and io_stall_write_ms column
2. base on @@IO_BUSY
Unfortunately both of them seems wrong... I know it's a little bold statement, but please take a look at my test and try to point out errors.
So my tests are divided on 2 parts, first part create empty database , create table and create procedure which inserts 200000 rows to table. Second part do snapshot of dm_io_virtual_file_stats and @@IO_BUSY before and after running procedure.
So main problem is :
without transaction timing on dm_io_virtual_file_stats seems correct, but with transaction it is totally strange - io_stall_write_ms is 2x bigger then elapsed time of whole test..- it could be possible with parallel processing but @@CPU_BUSY is just to low (Write time is much higher then CPU Usage - it's impossible in my universe :-) ) on the other hand @@IO_BUSY is surprisingly low for example. Whole test take 30 seconds and difference in snapshot on @@IO_BUSY is just 1 second..
Below print screen with wrong values:
GO
CREATE DATABASE [tester_1]
GO
use [tester_1]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tester](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[dat1] [datetime] NOT NULL,
[num1] [int] NULL,
[var1] varchar(1000) null,
[var2] varchar(4000) null,
[var3] varchar(4000) null
) ON [PRIMARY]
GO
----------------------------------------------
USE [tester_1]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE procedure [dbo].[run_insert] as
begin
DECLARE @RowCount INT
DECLARE @Random1 INT
DECLARE @Ranvar1 varchar(1000)
DECLARE @Ranvar2 varchar(4000)
DECLARE @Ranvar3 varchar(4000)
declare @dateDelete datetime
declare @sql varchar(max)
declare @alphabet varchar(1000) = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789asdafsdaf;;lqwoeiqrnbzml/lx[09304985234$%&#$%$@#%@#$@#%$GFADFGABBVCXXZCDASFASERQW$%$YYTqaoiqasl;dkjl;qw3093945890jlkxzv,l;z;ldal;jkpapoeoipqwerijujdkgjh;bvjkz\hdfoadsfpqwyuer9384t-2u84t9uafuihadsjkvnbzcx.na;jkdfhyqpweyp9q3843ut890ujreijhaogfhjfdnjva;sjd;asjhjqajheworqupoyu90-8427u58423yu5tuioerjght;lknhjgbjk;dfbjknznn.av;sdfaq;ojfoqpwer9p83u483u6908itjuwqearfASGHYGRTUTYRUI*OUP{O{POP:":L"JKL>NM<>B<VMCVNXCVBVZXV|AASAEWQER!#!@#%$$#^$%#&^%*&&^*&^*(*&)(*_)(+_{PIO":UI:HKGHMCVBNMCVNBXCBSDGFADSGQWRETQ@@TRWRE#TWERYTERYTYRUTYURITYUOYUIPYHUI:LHK:HLGJGFNCBNDGHSDFGGAQWWERTWQERTWEYTRYHYUYUJM&I<*OLI>(OP:?)__{"{*(L*IK&^%H%^YH^%$YH$ERTGWejoiwetfoi3u423iu5toirewkjkge;fags;lkerlk;weroipu423uo235i4joiewtjkore;glsojirqew9,[0m4t9,0mvuoierrwwucehmow409mtohuoowqfoicwqe980cq98-95420349c98ncu89pwt9pemmu89ewu98u98mtu89m324u982um82umum8qcopoqpiocrqewcqwcrqecrqwecrq453456576nui785im768o676ioin887aowejaslkjopiufqwer734-05892304uaojfas;ljdasoidfqp[uwer8901u423';
SET @RowCount = 0
WHILE (@RowCount < 200000)
BEGIN
set @Random1 = ROUND(((1200) * RAND() ), 0);
set @Ranvar1 =
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500);
set @Ranvar2 =
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500);
set @Ranvar3 =
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500);
INSERT INTO [dbo].[tester] with(rowlock,repeatableread)
([dat1],[num1],var1,var2,var3)
VALUES
(DATEADD(DAY, -@Random1, GETDATE())
,@Random1
,@Ranvar1
,@Ranvar2
,@Ranvar3);
set @RowCount = @RowCount + 1;
end;
end;
GO
GO
truncate table dbo.tester;
DECLARE @DateStart as datetime
DECLARE @DateEnd as datetime
set @DateStart = GETDATE();
select @DateStart as dateStart;
SELECT
mf.type,
mf.file_id,
mf.physical_name as FileName,
vfs.num_of_writes,
vfs.num_of_bytes_written,
vfs.io_stall_write_ms/1000.0 as io_stall_write_sec_before,
vfs.io_stall
FROM sys.dm_io_virtual_file_stats(NULL,NULL) AS vfs
inner join sys.master_files mf ON vfs.database_id = mf.database_id AND vfs.file_id = mf.file_id
where DB_NAME(vfs.database_id) = 'tester_1';
SELECT CAST(@@TOTAL_READ as bigint) as TotalRead
,CAST(@@TOTAL_WRITE as bigint) as TotalWrite
,(CAST(@@IO_BUSY as bigint) * @@TIMETICKS)/1000000 as IO_Busy_sec_before
,(CAST(@@CPU_BUSY as bigint) * @@TIMETICKS)/1000000 as Cpu_Busy_sec
,(CAST(@@IDLE as bigint) * @@TIMETICKS)/1000000 as Idle_sec;
--begin tran;
execute [dbo].[run_insert];
--commit tran;
SELECT
mf.type,
mf.file_id,
mf.physical_name as FileName,
vfs.num_of_writes,
vfs.num_of_bytes_written,
vfs.io_stall_write_ms/1000.0 as io_stall_write_sec_after,
vfs.io_stall
FROM sys.dm_io_virtual_file_stats(NULL,NULL) AS vfs
inner join sys.master_files mf ON vfs.database_id = mf.database_id AND vfs.file_id = mf.file_id
where DB_NAME(vfs.database_id) = 'tester_1';
SELECT CAST(@@TOTAL_READ as bigint) as TotalRead
,CAST(@@TOTAL_WRITE as bigint) as TotalWrite
,(CAST(@@IO_BUSY as bigint) * @@TIMETICKS)/1000000 as IO_Busy_sec_after
,(CAST(@@CPU_BUSY as bigint) * @@TIMETICKS)/1000000 as Cpu_Busy_sec
,(CAST(@@IDLE as bigint) * @@TIMETICKS)/1000000 as Idle_sec;
set @DateEnd = GETDATE();
select @DateEnd as dateEnd , DATEDIFF(SECOND,@DateStart, @DateEnd) as ElapsedTime_sec ;
GO
truncate table dbo.tester;
DECLARE @DateStart as datetime
DECLARE @DateEnd as datetime
set @DateStart = GETDATE();
select @DateStart as dateStart;
SELECT
mf.type,
mf.file_id,
mf.physical_name as FileName,
vfs.num_of_writes,
vfs.num_of_bytes_written,
vfs.io_stall_write_ms/1000.0 as io_stall_write_sec_before,
vfs.io_stall
FROM sys.dm_io_virtual_file_stats(NULL,NULL) AS vfs
inner join sys.master_files mf ON vfs.database_id = mf.database_id AND vfs.file_id = mf.file_id
where DB_NAME(vfs.database_id) = 'tester_1';
SELECT CAST(@@TOTAL_READ as bigint) as TotalRead
,CAST(@@TOTAL_WRITE as bigint) as TotalWrite
,(CAST(@@IO_BUSY as bigint) * @@TIMETICKS)/1000000 as IO_Busy_sec_before
,(CAST(@@CPU_BUSY as bigint) * @@TIMETICKS)/1000000 as Cpu_Busy_sec
,(CAST(@@IDLE as bigint) * @@TIMETICKS)/1000000 as Idle_sec;
begin tran;
execute [dbo].[run_insert];
commit tran;
SELECT
mf.type,
mf.file_id,
mf.physical_name as FileName,
vfs.num_of_writes,
vfs.num_of_bytes_written,
vfs.io_stall_write_ms/1000.0 as io_stall_write_sec_after,
vfs.io_stall
FROM sys.dm_io_virtual_file_stats(NULL,NULL) AS vfs
inner join sys.master_files mf ON vfs.database_id = mf.database_id AND vfs.file_id = mf.file_id
where DB_NAME(vfs.database_id) = 'tester_1';
SELECT CAST(@@TOTAL_READ as bigint) as TotalRead
,CAST(@@TOTAL_WRITE as bigint) as TotalWrite
,(CAST(@@IO_BUSY as bigint) * @@TIMETICKS)/1000000 as IO_Busy_sec_after
,(CAST(@@CPU_BUSY as bigint) * @@TIMETICKS)/1000000 as Cpu_Busy_sec
,(CAST(@@IDLE as bigint) * @@TIMETICKS)/1000000 as Idle_sec;
set @DateEnd = GETDATE();
select @DateEnd as dateEnd , DATEDIFF(SECOND,@DateStart, @DateEnd) as ElapsedTime_sec ;
I have real problem with getting right "Write time" statistics.
I'm trying 2 different approaches:
1. base on dm_io_virtual_file_stats and io_stall_write_ms column
2. base on @@IO_BUSY
Unfortunately both of them seems wrong... I know it's a little bold statement, but please take a look at my test and try to point out errors.
So my tests are divided on 2 parts, first part create empty database , create table and create procedure which inserts 200000 rows to table. Second part do snapshot of dm_io_virtual_file_stats and @@IO_BUSY before and after running procedure.
So main problem is :
without transaction timing on dm_io_virtual_file_stats seems correct, but with transaction it is totally strange - io_stall_write_ms is 2x bigger then elapsed time of whole test..- it could be possible with parallel processing but @@CPU_BUSY is just to low (Write time is much higher then CPU Usage - it's impossible in my universe :-) ) on the other hand @@IO_BUSY is surprisingly low for example. Whole test take 30 seconds and difference in snapshot on @@IO_BUSY is just 1 second..
Below print screen with wrong values:
TESTS:
---------------------------Prepare to test ----------------------------------------------------------\
USE [master]GO
CREATE DATABASE [tester_1]
GO
use [tester_1]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tester](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[dat1] [datetime] NOT NULL,
[num1] [int] NULL,
[var1] varchar(1000) null,
[var2] varchar(4000) null,
[var3] varchar(4000) null
) ON [PRIMARY]
GO
----------------------------------------------
USE [tester_1]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE procedure [dbo].[run_insert] as
begin
DECLARE @RowCount INT
DECLARE @Random1 INT
DECLARE @Ranvar1 varchar(1000)
DECLARE @Ranvar2 varchar(4000)
DECLARE @Ranvar3 varchar(4000)
declare @dateDelete datetime
declare @sql varchar(max)
declare @alphabet varchar(1000) = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789asdafsdaf;;lqwoeiqrnbzml/lx[09304985234$%&#$%$@#%@#$@#%$GFADFGABBVCXXZCDASFASERQW$%$YYTqaoiqasl;dkjl;qw3093945890jlkxzv,l;z;ldal;jkpapoeoipqwerijujdkgjh;bvjkz\hdfoadsfpqwyuer9384t-2u84t9uafuihadsjkvnbzcx.na;jkdfhyqpweyp9q3843ut890ujreijhaogfhjfdnjva;sjd;asjhjqajheworqupoyu90-8427u58423yu5tuioerjght;lknhjgbjk;dfbjknznn.av;sdfaq;ojfoqpwer9p83u483u6908itjuwqearfASGHYGRTUTYRUI*OUP{O{POP:":L"JKL>NM<>B<VMCVNXCVBVZXV|AASAEWQER!#!@#%$$#^$%#&^%*&&^*&^*(*&)(*_)(+_{PIO":UI:HKGHMCVBNMCVNBXCBSDGFADSGQWRETQ@@TRWRE#TWERYTERYTYRUTYURITYUOYUIPYHUI:LHK:HLGJGFNCBNDGHSDFGGAQWWERTWQERTWEYTRYHYUYUJM&I<*OLI>(OP:?)__{"{*(L*IK&^%H%^YH^%$YH$ERTGWejoiwetfoi3u423iu5toirewkjkge;fags;lkerlk;weroipu423uo235i4joiewtjkore;glsojirqew9,[0m4t9,0mvuoierrwwucehmow409mtohuoowqfoicwqe980cq98-95420349c98ncu89pwt9pemmu89ewu98u98mtu89m324u982um82umum8qcopoqpiocrqewcqwcrqecrqwecrq453456576nui785im768o676ioin887aowejaslkjopiufqwer734-05892304uaojfas;ljdasoidfqp[uwer8901u423';
SET @RowCount = 0
WHILE (@RowCount < 200000)
BEGIN
set @Random1 = ROUND(((1200) * RAND() ), 0);
set @Ranvar1 =
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500);
set @Ranvar2 =
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500);
set @Ranvar3 =
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500) +
substring(@alphabet, convert(int, rand()*500), 500);
INSERT INTO [dbo].[tester] with(rowlock,repeatableread)
([dat1],[num1],var1,var2,var3)
VALUES
(DATEADD(DAY, -@Random1, GETDATE())
,@Random1
,@Ranvar1
,@Ranvar2
,@Ranvar3);
set @RowCount = @RowCount + 1;
end;
end;
GO
---------------------------Prepare to test ----------------------------------------------------------/
-------------------------------Test without transaction values seems ok ---------------------------\
use [tester_1]GO
truncate table dbo.tester;
DECLARE @DateStart as datetime
DECLARE @DateEnd as datetime
set @DateStart = GETDATE();
select @DateStart as dateStart;
SELECT
mf.type,
mf.file_id,
mf.physical_name as FileName,
vfs.num_of_writes,
vfs.num_of_bytes_written,
vfs.io_stall_write_ms/1000.0 as io_stall_write_sec_before,
vfs.io_stall
FROM sys.dm_io_virtual_file_stats(NULL,NULL) AS vfs
inner join sys.master_files mf ON vfs.database_id = mf.database_id AND vfs.file_id = mf.file_id
where DB_NAME(vfs.database_id) = 'tester_1';
SELECT CAST(@@TOTAL_READ as bigint) as TotalRead
,CAST(@@TOTAL_WRITE as bigint) as TotalWrite
,(CAST(@@IO_BUSY as bigint) * @@TIMETICKS)/1000000 as IO_Busy_sec_before
,(CAST(@@CPU_BUSY as bigint) * @@TIMETICKS)/1000000 as Cpu_Busy_sec
,(CAST(@@IDLE as bigint) * @@TIMETICKS)/1000000 as Idle_sec;
--begin tran;
execute [dbo].[run_insert];
--commit tran;
SELECT
mf.type,
mf.file_id,
mf.physical_name as FileName,
vfs.num_of_writes,
vfs.num_of_bytes_written,
vfs.io_stall_write_ms/1000.0 as io_stall_write_sec_after,
vfs.io_stall
FROM sys.dm_io_virtual_file_stats(NULL,NULL) AS vfs
inner join sys.master_files mf ON vfs.database_id = mf.database_id AND vfs.file_id = mf.file_id
where DB_NAME(vfs.database_id) = 'tester_1';
SELECT CAST(@@TOTAL_READ as bigint) as TotalRead
,CAST(@@TOTAL_WRITE as bigint) as TotalWrite
,(CAST(@@IO_BUSY as bigint) * @@TIMETICKS)/1000000 as IO_Busy_sec_after
,(CAST(@@CPU_BUSY as bigint) * @@TIMETICKS)/1000000 as Cpu_Busy_sec
,(CAST(@@IDLE as bigint) * @@TIMETICKS)/1000000 as Idle_sec;
set @DateEnd = GETDATE();
select @DateEnd as dateEnd , DATEDIFF(SECOND,@DateStart, @DateEnd) as ElapsedTime_sec ;
-------------------------------Test without transaction values seems ok ---------------------------/
-------------------------------Test with transaction values seems wrong ---------------------------\
use [tester_1]GO
truncate table dbo.tester;
DECLARE @DateStart as datetime
DECLARE @DateEnd as datetime
set @DateStart = GETDATE();
select @DateStart as dateStart;
SELECT
mf.type,
mf.file_id,
mf.physical_name as FileName,
vfs.num_of_writes,
vfs.num_of_bytes_written,
vfs.io_stall_write_ms/1000.0 as io_stall_write_sec_before,
vfs.io_stall
FROM sys.dm_io_virtual_file_stats(NULL,NULL) AS vfs
inner join sys.master_files mf ON vfs.database_id = mf.database_id AND vfs.file_id = mf.file_id
where DB_NAME(vfs.database_id) = 'tester_1';
SELECT CAST(@@TOTAL_READ as bigint) as TotalRead
,CAST(@@TOTAL_WRITE as bigint) as TotalWrite
,(CAST(@@IO_BUSY as bigint) * @@TIMETICKS)/1000000 as IO_Busy_sec_before
,(CAST(@@CPU_BUSY as bigint) * @@TIMETICKS)/1000000 as Cpu_Busy_sec
,(CAST(@@IDLE as bigint) * @@TIMETICKS)/1000000 as Idle_sec;
begin tran;
execute [dbo].[run_insert];
commit tran;
SELECT
mf.type,
mf.file_id,
mf.physical_name as FileName,
vfs.num_of_writes,
vfs.num_of_bytes_written,
vfs.io_stall_write_ms/1000.0 as io_stall_write_sec_after,
vfs.io_stall
FROM sys.dm_io_virtual_file_stats(NULL,NULL) AS vfs
inner join sys.master_files mf ON vfs.database_id = mf.database_id AND vfs.file_id = mf.file_id
where DB_NAME(vfs.database_id) = 'tester_1';
SELECT CAST(@@TOTAL_READ as bigint) as TotalRead
,CAST(@@TOTAL_WRITE as bigint) as TotalWrite
,(CAST(@@IO_BUSY as bigint) * @@TIMETICKS)/1000000 as IO_Busy_sec_after
,(CAST(@@CPU_BUSY as bigint) * @@TIMETICKS)/1000000 as Cpu_Busy_sec
,(CAST(@@IDLE as bigint) * @@TIMETICKS)/1000000 as Idle_sec;
set @DateEnd = GETDATE();
select @DateEnd as dateEnd , DATEDIFF(SECOND,@DateStart, @DateEnd) as ElapsedTime_sec ;
-------------------------------Test with transaction values seems wrong ---------------------------/