Delayed Transaction Durability

Facebooktwitterredditpinterestlinkedinmail

Starting with SQL Server 2014, they added a feature called delayed transaction durability. This is a very interesting concept that could give you some speed improvements in your database. In this post, I will try to explain what this feature is and what some advantages/drawbacks are.

 
Transaction Log Durability
In 2014, SQL Server gives us the ability to control how the transaction log files are written to the disk. It gives us 2 options. Full transaction durability and Delayed transaction durability.

  • Full Transaction Durability – This is the default level. This means that as soon as a SQL transaction is executed, the transaction log is written to disk BEFORE control is sent back to the client/user.
  • Delayed Transaction Durability – This setting means that the SQL transactions will be written to a memory buffer instead of the disk. The control is then sent back to the client/user after writing to the memory buffer.

 
Advantages
The delayed transaction durability has a few distinct advantage over full transaction durability.

The first advantage is that it doesn’t need to write to disk before giving control back to the client. In many databases, writing to the disk provides a lot of contention. Log file writes to the disk can sometimes slow queries down quite a bit. Writing to memory is much faster and should speed up your queries in general if your IO to the disk is slow.

Another advantage is that the delayed transaction durability buffers the writes to disk. SQL Server can get optimizations by buffering the write operations. Instead of writing each transaction to the disk, it will fill a buffer and then flush that buffer all at once.

 
Disadvantages
Everything up to this point sounds great, right? Delayed transaction durability comes with one major pitfall. Delayed transaction durability could cause data loss if SQL Server crashes. The data that isn’t written to disk can be lost if SQL crashes.

When Should I Use Delayed Transaction Durability?
Only use delayed transaction durability if you can afford some data loss if SQL Server crashes. If you cannot afford any data loss, do not use delayed transaction durability.

 
How To Turn On/Off Delayed Transaction Durability
Okay, now that you’re an expert on delayed transaction durability, let’s quickly cover the 3 levels of transaction durability and how to activate them.

There are 3 kinds of transaction durability. Disabled, Allowed, and Forced.
DISABLED – This means delayed transaction durability is turned off. All transaction writes will go to disk and there will be no potential for loss.
FORCED – This means that delayed transaction durability is turned on for every query. All transaction writes will go to memory and there is a potential for data loss.
ALLOWED – This is kinda in the middle. It basically means that you can turn on the delayed transaction durability in the query or stored procedure.

You will configure the durability with one of these statements:

ALTER DATABASE zoobase SET DELAYED_DURABILITY = DISABLED

GO

ALTER DATABASE zoobase SET DELAYED_DURABILITY = FORCED

GO

ALTER DATABASE zoobase SET DELAYED_DURABILITY = ALLOWED

If you use ALLOWED, you will need to add this hint to your commit transaction in in your sql query or stored procedure to activate the delayed transaction durability for it:

BEGIN TRAN

UPDATE	Animal
SET		AnimalName = 'Cow'
WHERE	AnimalName = 'Cattle'

COMMIT TRAN WITH (DELAYED_DURABILITY = ON)

 
 
Reference: https://msdn.microsoft.com/en-us/library/dn449490.aspx

 
 
NOTE: SQL Server shutdown/reboots are handled the same way as a crash. Make sure you flush your transaction buffer before rebooting!

MAXDOP – SQL Server’s Way To Avoid Parallelism

Facebooktwitterredditpinterestlinkedinmail

SQL Server comes with built-in support for using parallelism for query execution. That means that SQL Server will split up the execution of a query among different CPUs if it thinks that it can get the query results faster that way. The default setting in SQL Server will use the number of CPU cores on the system as the maximum number of parallel processors to use. Okay… this is great, right?

 
The Grass Isn’t Always Greener
Although the thought of running 1 SQL query but using multiple processors sounds great, sometimes it can actually sometimes cause slower queries. A couple issues I have ran in to in our production environment are:

  • Sometimes the parallelism can take away CPU from other processes that are trying to run at the same time.
  • Sometimes the time that it takes to reassemble the results is longer than the not using parallelism. What this means is that when a query is split among different processors, it will need to merge them back together before it sends it to you. Sometimes this can be a longer task then just using 1 processor the whole time.

 
MAXDOP
MAXDOP is a query hint that can be added to the end of your SQL query to control the amount of parallelism that happens. When you use MAXDOP, you will specify the maximum number of parallelism threads that SQL Server uses for that query. In fact, the word MAXDOP stand for “Maximum Degree Of Parallelism”.

Here is an example of how to use the MAXDOP query hint to limit the number of parallel threads to 1 (essentially disabling the parallelism):

SELECT	*
FROM	Animal A
INNER	JOIN AnimalType AT ON AT.AnimalTypeID = A.AnimalTypeID
ORDER	BY A.AnimalName
OPTION	(MAXDOP 1)

To show how this affects the query, let me show you the execution plan when I supply the MAXDOP 1.
MAXDOP No Parallelism

Here is a screenshot of the execution plan of that exact same query without specifying the MAXDOP. You can see that it now uses parallelism.

MAXDOP Parallelism

 
Will Removing MAXDOP Help My Queries Run Faster
Is MAXDOP a silver bullet for making queries faster? No. In most cases you will just want SQL Server to manage the parallelism. This is usually the fastest/best way for your query to execute. But occasionally if you are having a slow query, you can try changing the MAXDOP setting. You will need to test your query before and after to see if there is significant improvement.

 
How Do You Know If Your Query Is Using Parallelism?
Here are a couple ways that I use to find out if parallelism is happening to a query.

  1. Check out the actual execution plan. After you run the query and the execution plan shows up, you will see a “Parallelism” step. You can see the screenshot above for what that looks like.
  2. Monitor the Activity Monitor in SQL Server Management Studio. This is a great way to detect if your production applications are causing parallelism. It’s really easy to see in Activity Monitor because it looks like the same line repeated many times.
    MAXDOP Activity Monitor

 
Reference: http://msdn.microsoft.com/en-us/library/ms181714.aspx

SQL Server 2014 Feature – Non-Clustered Indexes For Table Variables

Facebooktwitterredditpinterestlinkedinmail

This is truly an amazing feature to add to SQL Server 2014. I use table variables all the time and this was the only thing I didn’t like about them. Up to this point, SQL Server did not support having non-clustered indexes on table variables (the one with the name that starts with the @). If you wanted to do this, you had to create/use a temp table (the one with the name that starts with #).

With SQL Server 2014, they changed this and now allow the table variables to have non-clustered indexes as well. To do this, we simply add a little bit of extra code after the column declaration.

DECLARE	@AnimalTableVar	TABLE
( AnimalID		INT,
  AnimalName	VARCHAR(50)	INDEX IX_AnimalTempTable_AnimalName
)

In the sample above, we create a table variable called @AnimalTableVar. Then when we declare the column AnimalName, we add an index called IX_AnimalTempTable_AnimalName.

Here is how selecting from this table shows up in the execution plan!
Non-Clustered Indexes For Table Variables

Reference: http://msdn.microsoft.com/en-us/library/ms188927(v=sql.120).aspx

FORCE ORDER Query Hint

Facebooktwitterredditpinterestlinkedinmail

When querying out data, SQL Server has a ton of different query hints. One less commonly known query hint is FORCE ORDER. So here we will talk about what this query hint does and how we can use it efficiently.

FORCE ORDER
When you put this query hint on to your query, it tells SQL Server that when it executes the statement to not change the order of the joins in the query. It will join the tables in the exact order that is specified in the query. Normally the SQL Server optimizer will rearrange your joins to be in the order that it thinks will be optimal for your query to execute.

To use the FORCE ORDER query hint, you will want to add this at the end of your query.

 
Example Without FORCE ORDER

SELECT	*
FROM	Habitat H 
INNER	JOIN AnimalHabitat AH ON H.HabitatID = AH.HabitatID
INNER	JOIN Animal A ON AH.AnimalID = A.AnimalID

This is the actual execution plan without the FORCE ORDER hint. You can see that SQL Server starts at the table Animal and AnimalHabitat tables, then goes to the Habitat table. If you look at our query above, we clearly list the tables in the order of Habitat, AnimalHabitat, then Animal.

Execution Plan Without Force Order

 
Example With FORCE ORDER

SELECT	*
FROM	Habitat H 
INNER	JOIN AnimalHabitat AH ON H.HabitatID = AH.HabitatID
INNER	JOIN Animal A ON AH.AnimalID = A.AnimalID
OPTION	(FORCE ORDER)

In the screenshot below, it shows the actual execution plan with the FORCE ORDER hint. In the new query, you can see that SQL Server starts with the Habitat and AnimalHabitat tables and then moves to the Animal table. It does this because when we turn on the FORCE ORDER option, it uses the order of the tables specified in the query syntax.

Execution Plan With Force Order

 
What Is This Used For
The FORCE ORDER query hint is only used when you want to override the way that SQL Server wants to execute this query. Normally you will just let SQL Server figure out how to get the data from the database. It does such a good job at it, that you do not usually need to override this functionality.

Occasionally SQL Server will not figure out the most optimal way to pull this data out. In this case you may want to try this query hint.

List Of Data Types And Their Sizes

Facebooktwitterredditpinterestlinkedinmail

The below table shows the storage sizes of the different data types in SQL Server.

[table caption=”DateTime Data Types” th=”0″ width=”500″ colwidth=”150|150″]
date,3 bytes
datetime,8 bytes
datetime2,6 – 8 bytes (depending on precision)
datetimeoffset,10 bytes
smalldatetime,4 bytes
time,5 bytes
[/table]

[table caption=”Numeric Data Types” th=”0″ width=”500″ colwidth=”150|150″]
decimal,5 – 17 bytes
numeric,5 – 17 bytes
float,4 or 8 bytes
real,4 bytes
bigint,8 bytes
int,4 bytes
smallint,2 bytes
tinyint,1 byte
money,8 bytes
smallmoney,4 bytes
[/table]

[table caption=”String” th=”0″ width=”500″ colwidth=”150|150″]
char,size defined in table
varchar,2 bytes + data size
text,data size
nchar,2 times size defined in table
nvarchar,2 bytes + 2 times data size
ntext,2 times data size
[/table]

[table caption=”Binary” th=”0″ width=”500″ colwidth=”150|150″]
binary,size defined in table
varbinary,2 bytes + data size
image,2 bytes + data size
[/table]

[table caption=”Other” th=”0″ width=”500″ colwidth=”150|150″]
bit,1 byte
hierarchyid,5 bytes
uniqueidentifier,16 bytes
[/table]

Reference: http://msdn.microsoft.com/en-us/library/ff848794.aspx