I have a question regarding the under the hood parts of the History Table in the Temporal Tables feature of Microsoft's SQL Server.
To ask it I am going to create a hypothetical situation. Say I have a table with 300 columns in it. Each column has a char(10) in it. (3,000 bytes).
I insert a row into the main table.
I then go an modify one of the columns with an update statement. That causes the modified row to be inserted into the history table.
I then change that same column 4 more times (5 modifications total.)
What I am wondering is if that means that the size of my history table is now 3,000 x 5 = 15,000 bytes?
Or does it do some kind of compression under the hood to realize that most of the data did not change and does not need to be stored each time?
Best Answer
By default, the temporal table's history table is
PAGE
compressed.Source
Testing
Here is some pseudo code to create the table & add 300
char(10)
columnsWell, when using the query from this source
This is the result:
We get about 0.02 MB used for this history table, which is more than the 0.015mb specified.
However when we check SSMS, the details are lower.
Only 0.008 MB?
A simplified version of the query being run is this one:
Even more simplified, we see that the history table's clustered index data is only one data page;
Result
Why the difference?
This is due to the ssms query only considering
data_pages
. This differs fromused_pages
Consider this query:
Not all used_pages will be data_pages, while all data_pages will be used_pages.
There are overhead pages like
PFS
,GAM
,SGAM
,HEADER PAGE
etc.Summary
In our example, due to the
PAGE
compression, the data stored in the history table is in the8KB
range. This results in one data page used.The
SSMS
Query only considersdata_pages
, while the other query takes into account allused_pages
.For each update, an additional row is stored in the history table, without (page) compression, the data pages would amount to 2 (and be above or equal to 15k bytes).