Presentation is loading. Please wait.

Presentation is loading. Please wait.

Shaving of Microseconds

Similar presentations


Presentation on theme: "Shaving of Microseconds"— Presentation transcript:

1 Shaving of Microseconds
=tg= Thomas Grohser Shaving of Microseconds

2 select * from =tg= where topic =
Remark SQL 4.21 First SQL Server ever used (1994) SQL 6.0 First Log Shipping with failover SQL 6.5 First SQL Server Cluster (NT4.0 + Wolfpack) SQL 7.0 2+ billion rows / month in a single Table SQL 2000 938 days with 100% availability SQL 2000 IA64 First SQL Server on Itanium IA64 SQL 2005 IA64 First OLTP long distance database mirroring SQL 2008 IA64 First Replication into mirrored databases SQL 2008R2 IA64 SQL 2008R2 x64 First 256 CPUs & > STMT/sec First Scale out > STMT/sec First time 1.2+ trillion rows in a table SQL 2012 > Transactions per second > 1.3 Trillion Rows in a table SQL 2014 > Transactions per second Fully automated deploy and management SQL 2016 AlwaysOn Automatic HA and DR, crossed the PB in storage SQL 2017 In production 3 minutes after RTM, HA for Replication SQL vNext Can’t wait to push the limits even further =tg= Thomas Grohser, NTT DATA UK Senior Director Technical Solutions Architecture Focus on SQL Server Security, Performance Engineering, Infrastructure and Architecture Wrote some of Close Relationship with SQLCAT (SQL Server Customer Advisory Team) SCAN (SQL Server Customer Advisory Network) TAP (Technology Adoption Program) Product Teams in Redmond Active PASS member and PASS Summit Speaker 24 Years with SQL Server

3 Agenda

4 Agenda What this talks is about and what not! Shaving of micro seconds
Q&A

5 What this talk is NOT about

6 This talk is NOT about Query tuning Indexing strategies Schema design Hardware design In Memory OLTP How to make a 10 minute query run in 1 minute

7 This talk is about How to make a transaction that took 2ms run in 1ms Using very unusual tricks and some very obvious ones too…

8 WARNING

9 WARNING – WARNING - WARNING
Most of the presentation is extreme and should NOT be taken as best practice. In most cases the techniques here will make little difference but introduce a lot of work. This is for the cases where this extra work is required

10 Why is this needed?

11 Why is this sometimes needed
If you have a lot of tiny transactions every micro second counts. We have an auditing system that inserts 6 billion rows per day rows A day has only ms 2 ms per insert  139 cores 1 ms per insert  70 cores or ~½ million less in licenses

12 Let’s go

13 This is what we are going to make faster
CREATE TABLE FastInserts ( ID int PRIMARY KEY CLUSTERED IDENTITY(1,1), RecordInsertTime datetime DEFAULT (GETDATE()) NULL, AValueToBeStored decimal(38,2) NULL, AFlagToBeStored int NULL, ATextToBeStored nvarchar(30) NULL, ANumberToBeStored bigint NULL ); INSERT INTO FastInserts (ANumberToBeStored, AValueToBeStored, AFlagToBeStored, ATextToBeStored) VALUES (123, , 1, ' ’);

14 Cleanup Column Names CREATE TABLE FastInserts ( ID int PRIMARY KEY CLUSTERED IDENTITY(1,1), RecordInsertTime datetime DEFAULT (GETDATE()) NULL, Amount decimal(38,2) NULL, Flag int NULL, CreditCardNr nvarchar(30) NULL, UserAccountID bigint NULL ); INSERT INTO FastInserts (UserAccountID, Amount, Flag, CreditCardNr) VALUES (123, , 1, ' '); Understanding what data is stored in key to making it faster

15 The Obvious, Cleanup Data Types
CREATE TABLE FastInserts ( ID bigint PRIMARY KEY CLUSTERED IDENTITY(1,1), RecordInsertTime datetime2(7) DEFAULT (GETDATE()) NULL, Amount money NULL, Flag bit NULL, CreditCardNr varchar(16) NULL, UserAccountID int NULL ); INSERT INTO FastInserts (UserAccountID, Amount, Flag, CreditCardNr, TransactionTime) VALUES (123, , 1, ' ', ' :30:00’);

16 The Obvious, Cleanup Data Types
CREATE TABLE FastInserts ( ID bigint +4 RecordInsertTime datetime2(7) 0 Amount money -9 Flag bit -3 CreditCardNr varchar(16) -16, UserAccountID int -4 ); Total -28 bytes less on a 82 byte row This is up to 156 GB data or 33% less per day 1 ms per IO 256KB IO’s Checkpoint and 60KB log writes that’s 0.56 micro sec per row just on the IO or about 1h faster per day

17 One more byte: NOT NULL instead of NULL
CREATE TABLE FastInserts ( ID bigint PRIMARY KEY CLUSTERED IDENTITY(1,1), RecordInsertTime datetime2(7) DEFAULT (GETDATE()) NOT NULL, Amount money NOT NULL, Flag bit NOT NULL, CreditCardNr varchar(16) NOT NULL, UserAccountID int NOT NULL ); INSERT INTO FastInserts (UserAccountID, Amount, Flag, CreditCardNr) VALUES (123, , 1, ' ');

18 Four more bytes: varchar / char
CREATE TABLE FastInserts ( ID bigint PRIMARY KEY CLUSTERED IDENTITY(1,1), RecordInsertTime datetime2(7) DEFAULT (GETDATE()) NOT NULL, Amount money NOT NULL, Flag bit NOT NULL, CreditCardNr char(16) NOT NULL, UserAccountID int NOT NULL ); INSERT INTO FastInserts (UserAccountID, Amount, Flag, CreditCardNr) VALUES (123, , 1, ' '); 4 bytes metadata + 16 bytes = 20 bytes with 16 the most common we save 4 bytes

19 Prefix Object Reference with Schema Name
If not every time the query executes What is the default schema of the user If non specified what is the default schema of the DB This is two lookups on a very busy memory location requiring at least two latches and everyone else is waiting with a spinlock There is a reason in memory OLTP requires prefixes on all objects

20 Prefix Object Names Everywhere
CREATE TABLE dbo.FastInserts ( ID bigint PRIMARY KEY CLUSTERED IDENTITY(1,1), RecordInsertTime datetime2(7) DEFAULT (GETDATE()) NOT NULL, Amount money NOT NULL, Flag bit NOT NULL, CreditCardNr char(16) NOT NULL, UserAccountID int NOT NULL ); INSERT INTO dbo.FastInserts (UserAccountID, Amount, Flag, CreditCardNr) VALUES (123, , 1, ' '); This should be best practice everywhere

21 Make the Primary Key Random
CREATE TABLE dbo.FastInserts ( ID uniqueidentifier PRIMARY KEY CLUSTERED, UserAccountID int NOT NULL, RecordInsertTime datetime2(7) DEFAULT (GETDATE()) NOT NULL, Amount money NOT NULL, Flag bit NOT NULL, CreditCardNr char(16) NOT NULL, Pad char(19) NOT NULL, ); INSERT INTO dbo.FastInserts (ID, UserAccountID, Amount, Flag, CreditCardNr) VALUES (NEWID(), 123, , 1, ' ');

22 Make the Primary Key Random
With ever increasing key all inserts go to the end of the table creating a hotspot on the last page The more concurrent sessions the worst With ever increasing key at 300 concurrent sessions max of about 6000 inserts/second Random inserts go to over inserts/second on same hardware

23 Make the Primary Key Random

24 Make the row 32, 64, 128 bytes long CREATE TABLE dbo.FastInserts ( ID uniqueidentifier PRIMARY KEY CLUSTERED, UserAccountID int NOT NULL, RecordInsertTime datetime2(7) DEFAULT (GETDATE()) NOT NULL, Amount money NOT NULL, Flag bit NOT NULL, CreditCardNr char(16) NOT NULL, Pad char(7) NOT NULL, ); INSERT INTO dbo.FastInserts (ID, UserAccountID, Amount, Flag, CreditCardNr) VALUES (NEWID(), 123, , 1, ' '); Only helps later with reads, places rows in cache lines

25 Faster Query, place the SARGS in the front
CREATE TABLE dbo.FastInserts ( ID bigint PRIMARY KEY CLUSTERED IDENTITY(1,1), UserAccountID int NOT NULL, RecordInsertTime datetime2(7) DEFAULT (GETDATE()) NOT NULL, Amount money NOT NULL, Flag bit NOT NULL, CreditCardNr char(16) NOT NULL, ); SELECT … FROM dbo.FastInserts WHERE UserAccountID = 123; If all SARGS are in the first 64 bytes they are all fetched with a single cache line

26 Use BIN2 Collations All comparisons are much faster String1 = String2 Instead of are_these_equal(String1, String2) But your TSQL is now case sensitive if you do it on the server level Consider doing it just on DB or even just column level

27 CPU Affinity / IO Affinity

28 NUMA

29 … Soft NUMA IP/Port IP/Port IP/Port IP/Port IP/Port Core + Cache
Range of Data Range of Data Range of Data Range of Data Range of Data

30 Statement, Procedure, Prepared Statement
INSERT INTO dbo.FastInserts (ID, UserAccountID, Amount, Flag, CreditCardNr) VALUES (NEWID(), 123, , 1, ' ’); EXEC = = = = ' ’ stmt_id = Prepare Statement( INSERT INTO dbo.FastInserts (ID, UserAccountID, Amount, Flag, CreditCardNr) ) Execute = = = = ' '

31 Payload BINARY This is getting very extreme …
CREATE TABLE dbo.FastInserts ( ID uniqueidentifier PRIMARY KEY CLUSTERED, UserAccountID int NOT NULL, Data BINARY(48) NOT NULL ); INSERT INTO dbo.FastInserts (ID, UserAccountID, Data) VALUES (NEWID(), 123, 0x …); This is getting very extreme … Good luck reporting on this one

32 Shorten Names CREATE TABLE F.I ( I uniqueidentifier PRIMARY KEY CLUSTERED, U int NOT NULL, D BINARY(48) NOT NULL ); INSERT INTO F.I (I, U, D) VALUES (NEWID(), 123, 0x …);

33 Batching Inserts / Using Bulk
INSERT INTO dbo.FastInserts (ID, UserAccountID, Amount, Flag, CreditCardNr) VALUES (NEWID(), 123, , 1, ‘ '), (NEWID(), 124, , 0, ‘ '), (NEWID(), 125, , 1, ‘ '), (NEWID(), 126, , 1, ‘ '), (NEWID(), 127, , 0, ‘ '), (NEWID(), 128, , 1, ‘ '); or even better use the bulk insert API

34 Hardware High clock speed, disable cores to get faster cores Lots of cache Fast memory NV Memory for tail of the log NVMe disks direct attached for data and log Intelligent fast NIC (TCP offloading)

35 Thank You Q&A tg@grohser.com


Download ppt "Shaving of Microseconds"

Similar presentations


Ads by Google