What's slow on my database server?
A video investigating the relative performance of network, disk IO, and CPU on SQL Server.Here is the SQL that goes with the demo.
-- Database by Doug -- 10/8/2015 -- What's Slow Demo? -- for database performance -- There are 3 basic items to worry about: -- * IO -- * Network -- * CPU -- I see many people focus on them in this order: -- 1 - CPU -- 2 - IO -- 3 - network -- this demo should show that you should focus on them in this order: -- 1 - network -- 2 - IO -- 3 - CPU -- part 1: network vs IO use referencedb SET STATISTICS IO ON SELECT * FROM Person -- about 53 seconds -- while this runs, here's some basics about the setup: -- SQL Instance running as a virtual machine, no idea about the storage, general purpose -- synthetic data with reasonable data distributions -- 1.3M records -- average record size is about 456 bytes -- zero fragmentation -- total table size about 587MB -- some bogus fields for experimentation -- no non-clustered indexes --CREATE TABLE [dbo].[Person]( -- [ID] [int] IDENTITY(1,1) NOT NULL, -- [salutory] [nvarchar](15) NULL, -- [firstName] [nvarchar](25) NULL, -- [middleInitial] [nchar](1) NULL, -- [lastName] [nvarchar](25) NOT NULL, -- [nameSuffix] [nvarchar](8) NULL, -- [email] [nvarchar](255) NULL, -- [entryDate] [datetime] NOT NULL CONSTRAINT [DF_Person_entryDate] DEFAULT (getdate()), -- [lastUpdateDate] [datetime] NOT NULL CONSTRAINT [DF_Person_lastUpdateDate] DEFAULT (getdate()), -- [weight] [float] NULL, -- [gender] [char](1) NULL, -- [dateOfBirth] [date] NULL, -- [bogusGUID] [uniqueidentifier] ROWGUIDCOL NULL CONSTRAINT [DF_Person_bogusGUID] DEFAULT (newid()), -- [bogusGUID2] [uniqueidentifier] NULL CONSTRAINT [DF_Person_bogusGUID2] DEFAULT (newid()), -- [bogusChar] [char](100) NOT NULL CONSTRAINT [DF_Person_bogusChar] DEFAULT ('fred'), -- [bogusNChar] [nchar](100) NOT NULL CONSTRAINT [DF_Person_bogusNChar] DEFAULT (N'george'), -- CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ( [ID] ASC) --) ON [PRIMARY] -- ok, so what about this? SELECT TOP 1 ID FROM Person -- one record, one value, 4 bytes -- 0 seconds - the time for a round trip -- so what is slow? SELECT ID FROM Person -- 1.3M records, 4 bytes each -- about 4 seconds SELECT ID, ID FROM Person -- 1.3M records, 8 bytes each -- about 5 seconds SELECT bogusGuid FROM Person -- 1.3M records, 16 bytes each -- about 5 seconds SELECT bogusGUID, bogusGUID2 FROM Person -- 1.3M records, 32 bytes each -- about 6 seconds SELECT 75804 * 8/1024 SELECT bogusGUID, bogusGUID2, '1234567890' FROM Person -- 1.3M records, 42 bytes each -- about seconds SELECT bogusGUID, bogusGUID2, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' FROM Person -- 1.3M records, 132 bytes each -- about 16 seconds SELECT bogusGUID, bogusGUID2, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' FROM Person -- 1.3M records, 232 bytes each -- about 27 seconds -- keep going, and you get a graph that looks like ... -- but you are cheating - you have all your data in memory... -- now starve the db server for memory /** sp_configure 'show advanced options', 1; GO RECONFIGURE; GO sp_configure 'max server memory', 256; GO RECONFIGURE; GO **/ SELECT ID FROM Person -- 1.3M records, 4 bytes each -- about 4 seconds -- network is slower than IO -- even with physical IO -- ************************************************** /** sp_configure 'show advanced options', 1; GO RECONFIGURE; GO sp_configure 'max server memory', 2147483647; GO RECONFIGURE; GO **/ -- part 2: IO vs CPU SELECT AVG(weight) FROM Person -- 1.3M records, but only 8 bytes back -- about 0 seconds -- can we make it worse? -- can we make the CPU worse? SELECT weight FROM Person -- 1.3M records, 8 bytes back per record -- 4 seconds SELECT MAX(weight) FROM Person -- about 0 seconds SELECT AVG(LOG(weight/1.7)) FROM Person -- 1.3M records, 8 bytes back -- about 0 seconds SELECT AVG(SQRT(LOG(weight/1.7))) FROM Person -- about 0 seconds SELECT AVG(SIN(SQRT(LOG(weight/1.7)))) FROM Person -- about 0 seconds SELECT AVG(SIN(SQRT(10+3.3*LOG(weight/1.7)))) FROM Person -- about 1 seconds SELECT AVG(SIN(SQRT(10+3.3*LOG(weight/1.7)))*PI()) FROM Person -- about 1 seconds -- taking just the average out SELECT (SIN(SQRT(10+3.3*LOG(weight/1.7)))*PI()) FROM Person -- 4 seconds -- you can do tons of calculations, and not impact speed -- summary: focus on items in this order -- 1 - network -- 2 - IO -- 3 - CPU -- caveats: -- your mileage may vary -- use your own judgement -- this is the order in which I do investigations on a new database -- end of what's slow
Can you go over how you approach network and IO issues.
ReplyDelete