För er som missat Paul Randals session om myterna med SQL Server kommer här ett…
EDIT: Also read this blogpost: https://sqlservice.se/sv/start/blogg/sql-azure-followup.aspx , that gives more context to the findings in this post.
Today we will take a look at the INSERT speed of SQL Azure, compared to my laptop. So I did the following on both my HP ENVY i5 Laptop and 1 internal spinning disc and SQL Server 2008 R2, and my SQL Azure Web edition database.
I created 2 tables with clustered indexes:
CREATE TABLE [dbo].[TableTest]( [Int_Col] [int] IDENTITY(1,1) NOT NULL, [Varchar_Col] [varchar](50) NOT NULL, [Datetime_Col] [datetime] NOT NULL, [GUID_Col] [uniqueidentifier] NOT NULL )
ALTER TABLE [dbo].[TableTest] ADD CONSTRAINT [DF_TableTest_Varchar_Col] DEFAULT ('Varchar_Col') FOR [Varchar_Col] ALTER TABLE [dbo].[TableTest] ADD CONSTRAINT [DF_TableTest_Datetime_Col] DEFAULT (getdate()) FOR [Datetime_Col]
ALTER TABLE [dbo].[TableTest] ADD CONSTRAINT [DF_TableTest_GUID_Col] DEFAULT (newid()) FOR [GUID_Col]
GO
CREATE CLUSTERED INDEX [ix_tabletest] ON [dbo].[TableTest] ( [GUID_Col] ASC )
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
CREATE TABLE [dbo].[results]
( [GUID] [uniqueidentifier] NOT NULL, [test] [varchar](50) NULL, [starttime] [datetime2](7) NULL, [endtime] [datetime2](7) NULL, [rownr] [bigint] NULL, [Runtime_MS] AS (datediff(millisecond,[starttime],[endtime])), [Rows_pr_ms] AS (isnull(CONVERT([decimal],[rownr],0)/datediff(millisecond,[starttime],[endtime]),(0))) ) GO
CREATE CLUSTERED INDEX [ix_results] ON [dbo].[results] ( [GUID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) GO CREATE TABLE [dbo].[guidtbl]( [GUID] [uniqueidentifier] NOT NULL )
CREATE CLUSTERED INDEX [ix_guidtbl] ON [dbo].[guidtbl] ( [GUID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) GO
Then I created A stored proc:
create proc [dbo].[insert_test] @rows int as SET NOCOUNT ON SET STATISTICS IO OFF SET STATISTICS TIME OFF truncate table guidtbl insert guidtbl (GUID) Values (NEWID()) TRUNCATE TABLE [dbo].[TableTest] Declare @GUID uniqueidentifier select @GUID = guid from guidtbl Insert results ([GUID], test, starttime) values (@GUID, 'INSERT_Test', getdate()) declare @i int select @i = 0 while @i < @rows begin INSERT INTO [dbo].[TableTest] ([Varchar_Col] ,[Datetime_Col] ,[GUID_Col]) VALUES (default ,default ,default) select @i = @i + 1 end Update results set endtime = getdate() where test = 'Insert_Test' and endtime IS NULL DECLARE @rownr int select @rownr = count(*) from TableTest update results set rownr = @rownr where test = 'Insert_Test' and rownr IS NULL GO
And then I executed it: exec dbo.insert_test 100000
The results? After a few testruns the results table looks like this on SQL AZURE: select * from results 
The conclusion? My Laptop is faster than SQL Azure! Atleast when it comes to pure INSERT performance.
The reason? Obviously I can’t be 100% sure about why. But having repeated the test on several other servers, I have reached the following conclusion: The INSERT performance problems in SQL AZURE is likely caused by the underlying IO subsystem, particularly on the drive that holds the logfile, and by the fact that you have 3 redundant copies of your database. Using this script by Håkan Winther, I captured the following snapshots of what I am waiting for during the INSERT test: 

