Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Server

SQL Server 2012 : Latch Contention Examples - Inserts When the Clustered Index Key Is an Identity Field

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
8/24/2014 9:17:11 PM

All of the code in this section uses the Ch7Examples.sql code file.

This section looks at a couple of examples demonstrating contention issues involving latches and spinlocks. Some of these examples are borrowed from various presentations involving the SQLCAT team at SQLBits events in the U.K., and we are indebted to Thomas Kejser in particular for his work on these.

Inserts When the Clustered Index Key Is an Identity Field

A lot of advice suggests using an identity field for the clustered index on a table. Certainly there are benefits to doing this. An identity field is typically an int or bigint type, making it relatively small compared to some other candidates for primary keys, in particular uniqueidentifier fields, which can cause frequent page splits, as well as being overly large, especially because clustered index keys appear in nonclustered indexes as well.

However, for tables that use identity fields for clustered index keys, when the number of inserts scales up, the final page will become “hot,” and contention could occur.

Consider the scenario in which a lot of processor cores are trying to insert data into the same page. The first session to reach the page in question will obtain a PAGELATCH_EX latch; but in the same moment, a large number of other threads might also be trying to acquire a PAGELATCH_EX latch. There would also be PAGELATCH_SH latches acquired at the higher index levels, to allow these pages to be traversed. If the insert needs to tip onto a new page, then a PAGELATCH_EX would be required at the next index level higher.

If sys.dm_os_waiting_tasks were queried during heavy inserts, it would likely show PAGELATCH_EX waits, with the resource_description column showing the page of note. The page could be examined, with DBCC PAGE, and identified as the table under stress.

The point here is not to make a case against ever using an identity field for a clustered index. In many systems, it’s still an excellent idea. However, if you’re seeing a large amount of latch contention during busy periods of insertion into such a table, then this design choice may certainly be a contributor to the predicament.

The solution has to move the activity away from the hotspot of insertion. While this could be done by simply replacing the identity field with a new uniqueidentifier field, populated with newid() values, the same goal can be achieved in other ways. One way of spreading the load sufficiently without losing the benefits of having a small clustered index, with the data nicely arranged in a b-tree, is to introduce partitioning. This way, the table is spread across a number of b-tree structures, instead of just one. With a bit of planning, the activity can be spread across the partitions. There may still be a hotspot for each partition, but this could well be enough to relieve the stress on the problem page.

The following example assumes that eight partitions are wanted, but you could choose whatever number suited your needs. All the partitions can be put on the same filegroup; this exercise is not designed to use partitions to spread the table across multiple filegroups, but merely to make additional b-tree structures to store the table.

CREATE PARTITION FUNCTION pf_spread (TINYNT) AS RANGE LEFT FOR VALUES
(0,1,2,3,4,5,6);
CREATE PARTITION SCHEME ps_spread AS PARTITION pf_spread ALL TO (PRIMARY);

To spread the data across your various partitions, you simply need to introduce into the table a column that causes the data to be distributed. In this case, ID % 8 will do nicely:

ALTER TABLE MyStressedTable
ADD PartID AS CAST(ID % 8 AS TINYINT) PERSISTED NOT NULL;

Once this is done, the clustered index simply needs to be created on the partitions:

CREATE UNIQUE CLUSTERED INDEX cixMyStressedTable (ID, PartID) ON ps_spread(PartID);

Now, inserts will be cycled around the eight partitions, which should enable many more inserts to be done before latch contention occurs. Going back to the analogy using the chairs at a party, this partitioning provides seven more chairs. If the number of threads being used to perform the inserts is such that there is now a very small number of threads per b-tree, then the likelihood of contention is very much reduced.

Of course, additional partitions might translate into more work finding data using the ID field. A query that simply filters on the ID field would need to search all eight partitions, despite the fact that you can see a correlation between the ID and the partition. To avoid having to search across all the partitions, code such as

SELECT *
FROM dbo.MyStressedTable
WHERE ID = @id;

should be changed to

SELECT *
FROM dbo.MyStressedTable
WHERE ID = @id
AND PartID = CAST(@id % 8 AS TINYINT);

Other -----------------
- SQL Server 2012 : Latches and Spinlocks - Monitoring Latches and Spinlocks
- SQL Server 2012 : Latches and Spinlocks - SuperLatches/Sublatches
- SQL Server 2012 : Latches and Spinlocks - Latch Types, Latch Modes
- Sharepoint 2013 : Overview of The Client-Side Object Model and Rest APIs - Client-Side Object Model API Coverage
- Sharepoint 2013 : Overview of The Client-Side Object Model and Rest APIs - REST and OData (part 3) - Creating, Updating, and Deleting
- Sharepoint 2013 : Overview of The Client-Side Object Model and Rest APIs - REST and OData (part 2) - Filtering and Selecting
- Sharepoint 2013 : Overview of The Client-Side Object Model and Rest APIs - REST and OData (part 1) - Getting Started with REST and OData
- Sharepoint 2013 : Integrating Apps for Office with SharePoint (part 2) - Apps for Office Integrated with an App for SharePoint
- Sharepoint 2013 : Integrating Apps for Office with SharePoint (part 1) - Standalone Apps for Office
- Sharepoint 2013 : The Office JavaScript Object Model (part 3) - App Security
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
 
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server