Adding a column to a table with nonclustered columnstore index - sql-server

Adding a column to a table that has a nonclustered columnstore index on it is not a problem, but is it possible to add a column to nonclustered columnstore index itself without dropping it and creating again?

Related

Change Data Capture cannot be enabled on a table with a clustered columnstore index. Consider dropping clustered columnstore index

I am getting the below error when trying to enable CDC on a table with a clustered columnstore index:
Change Data Capture cannot be enabled on a table with a clustered columnstore index. Consider dropping clustered columnstore index
But I need to have both CDC and clustered columnstore index on the same table.
Is there any workaround to this limitation?
The workaround to this is to enable CDC first and then to create a clustered columnstore index.
Drop a clustered columnstore index if exists.
Enable CDC.
Create a clustered columnstore index.
Voila! It works!

Parallel clustered columnstore index build

Is it possible to build clustered columnstore index using several processes and keeping the row order of clustered rowstore index? Table is partitioned. Currently I am converting rowstore index to columnstore like this:
CREATE CLUSTERED columnstore INDEX [index_name] ON schema.table
WITH (
drop_existing = ON
,MAXDOP = 1
)
If I increase MAXDOP, then row order isn't kept. I am thinking about creating separate table for every partition and then doing partition switching. Maybe there is a better way?

Multiple Clustered Indexes on a Single Table?

I thought we could only place one clustered index on one table, and put multiple non-clustered indexes on a table, but using the code below I can easily add more than one clustered index to my table.
CREATE CLUSTERED INDEX TBL_MULTI_LC_HIST ON dbo.TBL_MULTI_LC_HIST (ID,AsOfDate)
Is this completely wrong?
It isn't possible to create multiple clustered indexes for a single table. From the docs (emphasis mine):
Clustered indexes sort and store the data rows in the table or view based on their key values. These are the columns included in the index definition. There can be only one clustered index per table, because the data rows themselves can be stored in only one order.
For example this will fail:
CREATE TABLE Thing
(
Column1 INT NOT NULL,
Column2 INT NOT NULL
)
CREATE CLUSTERED INDEX IX1 ON dbo.Thing(Column1)
CREATE CLUSTERED INDEX IX2 ON dbo.Thing(Column2)
Error:
Cannot create more than one clustered index on table 'dbo.Thing'. Drop the existing clustered index 'IX1' before creating another.
Example: http://www.sqlfiddle.com/#!18/53a63/1
You can however have a single index with multiple columns in it which is perhaps where you are getting confused:
CREATE CLUSTERED INDEX IX3 ON dbo.Thing(Column1, Column2)
You can only have one clustered index. A "Clustered" index IS the row... it contains all the columns. Every other index would just contain a pointer to the clustered row. The key of the clustered index enforces an 'ordering' on the rows by default.
If there is no clustered index, then the rows are basically stored in a heap, with no order or structure.

How to speed up recreating cluster index

In SQL Server, there is no option for altering the cluster index if i want to add one new column to cluster index definition. The only option is to drop and create cluster index with new definition.
From what I understand, drop and create of cluster index is a very costly and time consuming for high volume tables.
Cluster index recreate rebuilds all the nonclustered indexes on a table which can be very expensive.
The question to this forum "is there anyway we can speed up cluster index recreating"
The one workaround what I can think is to drop all non-cluster index before recreating cluster index. Will this approach work ?
Use
CREATE .... WITH (DROP_EXISTING = ON)
Instead of
DROP ...
CREATE ...
This means the non clustered indexes only have to be updated once (to include the new key column). Not twice - first to use the physical rid and then again to use the new CI key.
The DROP_EXISTING clause tells SQL Server that the existing clustered index is being dropped but that a new one will be added in its place, letting SQL Server defer updating the nonclustered index until the new clustered index is in place..
Additionally, SQL Server won't rebuild the nonclustered index at all if the clustered index key doesn't change and is defined as UNIQUE, which isn't an obvious performance benefit of defining a clustered index as UNIQUE
Example
CREATE TABLE #T
(
A INT,
B INT,
C INT
)
CREATE CLUSTERED INDEX IX ON #T(A)
CREATE CLUSTERED INDEX IX ON #T(A,B) WITH (DROP_EXISTING = ON)
DROP TABLE #T

Unique Clustered Index - can I make non-unique without drop/create

I have a unique clustered index that is causing replication problems (see "bounded updates"). Is there any way, short of dropping the clustered index, to make the index non-unique?
Is the clustered index also the primary key? If the clustered index is the primary key, then a unique clustered is also created. This mean you have to drop and create.
If the clustered index is not the primary key, you can use with drop existing to drop/create the index.
e.g.
create clustered index MyIndex on MyTable(MyColumn[s]) with(drop_existing=on);

Resources