Computed Columns can be stored in the data page in one of two ways. Either by creating them as PERSISTED
or by including them in the clustered index definition.
If they are included in the clustered index definition then even if the columns are not marked as PERSISTED
then the values will still be stored in each row. These index key values will additionally be stored in the upper level pages.
If the computed column is imprecise (e.g. float
) or not verifiable as deterministic (e.g. CLR functions) then it is a requirement for the column to be marked as PERSISTED
in order to be made part of an index key.
So to give an example
CREATE TABLE T
(
A INT,
C1 AS REPLICATE(CHAR(A),100) PERSISTED,
C2 AS REPLICATE(CHAR(A),200),
C3 AS CAST(A AS FLOAT) PERSISTED,
C4 AS CAST(A + 1 AS FLOAT)
)
CREATE UNIQUE CLUSTERED INDEX IX ON T(C2,C3)
C1
will be stored in just the data page rows as it is marked as
PERSISTED
but not indexed.
C2
will be stored in both the rows on the data page and the index higher levels as it is an index key column.
C3
will be stored as for C2
. As it is imprecise
it is a requirement to mark it as PERSISTED
however.
C4
won't be stored anywhere as it is neither marked as PERSISTED
nor indexed.
Similarly all computed columns referenced in non clustered index definitions as key columns need to be stored at all levels of the index as they are part of the index key. There is the same requirement regarding precise/deterministic results.
Fails
CREATE NONCLUSTERED INDEX IX2 ON T(A,C4)
With the error.
Cannot create index or statistics 'IX2' on table 'T' because the
computed column 'C4' is imprecise and not persisted. Consider removing
column from index or statistics key or marking computed column
persisted.
To include it as part of the non clustered index key it must also be stored in the clustered index data pages. However
Succeeds.
CREATE NONCLUSTERED INDEX IX2 ON T(A) INCLUDE (C4)
Computed columns that are only INCLUDE
d columns are persisted to the NCI leaf page and do not have the requirement that they also be persisted in the data page.
There has to be some invariant between two versions to say the versions relate to the same thing. This is the job of the primary key. It exists to differentiate this thing from that thing and to say that all that stuff over there relates to this one thing over here, via the foreign key of stuff.thing_id. If you change the primary key - Name, or GroupID in your case - you have a new thing, not an old thing with a new name. This is one of the reasons we have impersonal identification like social security numbers.
You have a couple of options. A) re-design your tables so there is an invariant identifier. An integer surrogate key works well for this. B) add two columns Previous_Version_Name
and Previous_Version_GroupID
. Populate these as you accumulate values for the new version. Use them in your join. "A" would be better.
You may also want to think about using a partitioned table and / or views rather than move data around between TableA and TableB yourself.
Best Answer
It is possible to check if an index using a number of columns exists.
Is one (a bit convoluted) way to do that.
But as aasim.abdullah noted in a comment, two indexes on the same set of columns but in different order, aren't the same. And it is possible to have both indexes side by side.