Read this before using SQL 2016 Temporal Tables

I’ve been testing the new Temporal Tables feature over the past day to see about using it in one of our production databases. It’s a neat feature that honestly adds a boat load of possibility around logging.

In my testing I noticed that user created tables seem to store the rows over quite a bit more pages. User created history tables were nearly double the size of an auto generated one. If you’re currently using the feature or plan to use it in the near future, you’ll want to think about this storage issue before you implement.

If you’re not aware of what Temporal tables are, they are like a running history of your table. You can read more about them here:

As you can see the system generated table is nearly half the size of the user created table. I scripted the tables to compare and they were the same! I then looked at Object Explorer and noted that the system generated table actually had a bit more (clustered PK and some defaults).

Why is the table SQL generated so much smaller?

Towards the end of the weekend I decided to pick this up again and I looked at sys.partitions. Here’s what I found:

That’s right! When SQL generates your table for you it adds a clustered index and also applies page compression.

Summing up – the takeaways

To make things very easy and ensure the table is as optimal as it can be, I recommend letting SQL Server 2016 create your history table. Give it a meaningful name; but, let SQL created it for you.

This will ensure that page compression is enabled on the history table and will create an index that may be useful as well.

I hope you’ve found this post helpful! If you did be sure you check out my other posts:

I’m using SQL Server 2017 (RTM-CU9-GDR) (KB4293805) – 14.0.3035.2, and I’m seeing a different result than yours; my history tables are not compressed, and there is a clustered index on ValidFromUTC+ValidToUTC. Do you have any guesses as to why there is a difference?