Database Reference
In-Depth Information
SQL Server maintains another unique timestamp, TransactionId , and it increments and assigns it to the
transaction when it starts. TransactionId is used as a temporary value for BeginTs and EndTs timestamps in the rows
created or deleted by uncommitted transactions. We will discuss this process in detail later in the chapter.
Every statement in a transaction has a unique 4-byte StmtId value. The third element in a row header is the
StmtId of the statement that is inserted a row. It works as a Halloween protection technique, similar to Table Spools in
on-disk tables, and it allows the statement to skip rows it inserted. You can think about the INSERT INTO T SELECT
FROM T statement as the classic example of such a situation.
We discussed the Halloween Protection technique and table Spools in Chapter 25, “Query Optimization
and execution.”
Note
In contrast to on-disk tables, where nonclustered indexes are separate data structures, all indexes in
memory-optimized tables reference actual data rows. Each new index that is defined on a table adds a pointer to a
data row. For example, if a table has two indexes defined, every data row in a table would have two 8-byte pointers
that reference the next data rows in the index chains. This, in a nutshell, makes every index in memory-optimizing
tables covering; that is, when SQL Server locates a row through an index, it finds the actual data row rather than the
separate index row structure.
The next element in the header, 2-byte IdxLinkCount , indicates how many indexes (pointers) reference the row.
SQL Server uses it to detect rows that can be deallocated by the garbage collection process.
An array of 8-byte index pointers is the last element of the row header. As you can guess, every memory-optimized
table should have at least one index to link data rows together. At most, you can define eight indexes per memory-optimized
table, including the primary key.
The actual row data is stored in the Payload section of the row. As already mentioned, the Payload format may
vary depending on the table schema. SQL Server works with Payload through a DLL that is generated and compiled at
the time of table creation.
A key principle of in-memory OLTP is that Payload data is never updated. When a table row needs to be updated,
Hekaton sets the EndTs attribute of original row to the Global Transaction Timestamp of the transaction and inserts the
new version of the data row with the new BeginTs and EndTs values of Infinity . We will see how this works in detail shortly.
Hash Indexes
Hash indexes are one of two index types supported by in-memory OLTP. They consist of an array of hash buckets, each
of which contains a pointer to a data row. SQL Server applies a hash function to the index key columns, and the result
of the function determines to which bucket a row belongs. All rows that have the same hash value and belong to the
same bucket are linked together through a chain of index pointers in the data rows.
Figure 32-3 illustrates an example of a memory-optimized table with two hash indexes defined on the Name and
City columns. Solid arrows represent pointers in the index on the Name column. Dotted arrows represent pointers in
the index on the City column. For simplicity sake, let's assume that the hash function generates a hash value based on
the first letter of the string.
 
 
Search WWH ::




Custom Search