create column store index on all supported tables in sql server 2014 copy
TRANSCRIPT
Database Administration Community (https://mostafaelmasry.wordpress.com)
Create Column Store index on all Supported tables in SQL
SERVER 2014
Writer: Mustafa EL-Masry
Technical Reviewer: SQLSERVER Performance tuning (http://sqlserver-performance-tuning.net/)
Published: Jan 2015
Applies to: SQL Server 2008 R2, 2012
About The Writer
I am Mustafa El-Masry Microsoft Senior Database Administrator – DB Analyst and Database
Performance Specialist also I am author and technical Writer
I am Microsoft Certified IT professional in SQL Server Administration and Development 2008 MCTS,
MCTIP I working now in MCSA, MCSE in SQL Server 2012 and I preparing myself to MVP
award (Microsoft Most Valuable Professional)
I have deep practical knowledge about T-SQL performance , HW
Performance issues, Data Warehousing and data mart solutions , SQL
Server Replication, Clustering solutions (Active Active and active
passive)and Database Designs for different kinds of systems , HAG, i
worked on All SQL Server Versions (2005,2008,2008R2,2012,2014) diving
deeply more check the below information about me
I am Founder of Community: SQL
DATABASE ADMINISTRATION: http://mostafaelmasry.wordpress.com/
Linked in: https://www.linkedin.com/in/mostafaelmasry
My Community Annual report : https://mostafaelmasry.wordpress.com/2014/annual-report/
I am Technical Writer and Reviewer : http://www.slideshare.net/MostafaElmasry3/
I am Audience Marketing Manager and Executive Board member: SQLSERVER PERFORMANCE
TUNING http://sqlserver-performance-tuning.net/
One Hundred POST :http://sqlserver-performance-tuning.net/?p=5244
Fluent Participator at Microsoft Forums of SQL Server at http://Social.technet.microsoft.com
More than +175 Post in SQL Server Technology: http://sqlserver-performance-tuning.net/?p=4526
Microsoft Profile: https://www.mcpvirtualbusinesscard.com/VBCServer/EngMostafaElamsry/profile
Database Administration Community (https://mostafaelmasry.wordpress.com)
Hi Guys in the last Script for How to can Create Clustered ColumnStore Index VI i explained the idea for
the Script after my work and more workshop i do more updates on the Script to be more easy and more
comprehensive version two will do 90 % from the operation of How to create Clustered column Store
index on your usage databases in one click let’s go to know at the first what is Column Store index
before going for the DEMO PART:
Our Script will cover utmost importance and sensitivity parts for How to Create Clustered Column Store
index:
1. List by Supported tables and Non Supported tables
2. Drop foreign key for Supported Tables with the Rollback.
3. Drop Clustered and Non Clustered index on Supported tables with the Rollback
4. Create Clustered Column Store index on all supported table (Contain the last three Scripts Sufficient for
the purpose)
NOTE: Script not creates anything direct on your database only print and you can check it first then
execute it.
Introduction about Clustered ColumnStore Index:
New index type released in SQL SERVER 2014 Creates an in-memory clustered columnstore index on a
SQL Server table. Use a clustered columnstore index to improve data compression and query
performance for data warehousing workloads that primarily perform bulk loads and read-only queries.
Since the clustered columnstore index is updateable, the workload can perform some insert, update,
and delete operations. Improvement in Column Store Index in SQL SERVER 2014:
With SQL Server 2014 you can create a columnstore index without having much impact on write -
ability on the table not like NonClustered Column
Store index in SQL Server 2012 when we create a
column store index and it makes the table read only.
This means you can issue some INSERT, UPDATE,
DELETE statements with a table with clustered
columnstore index. No more tedious workaround is
required for writing data to a table with columnstore
index in this release like the previous release.
For columnstore index, ALTER INDEX … REBUILD has a
new COLUMNSTORE_ARCHIVE data compression
option that further compresses the specified
partitions of a columnstore index, resulting in even less disk space being used. You can use this
option for archival, or for other situations that require a smaller data storage size and can afford
more time for storage and retrieval.
Database Administration Community (https://mostafaelmasry.wordpress.com)
Basic Syntax of Create Column Store Index:
Column Store index in SQL Server 2014 CREATE CLUSTERED COLUMNSTORE INDEX index_name ON table_name WITH ( DROP_EXISTING OR MAX_DOP) ON partition_scheme_name | filegroup_name | default
Column Store index in SQL Server 2012 CREATE NONCLUSTERED COLUMNSTORE INDEX index_name ON table_name COLUMN columns_name WITH ( DROP_EXISTING OR MAX_DOP) ON partition_scheme_name | filegroup_name | default
Remember:
In SQL Server 2014, you can still create a non-clustered columnstore index as you can in SQL Server
2012 though the non-clustered columnstore index is used for read-only queries, and is not
updateable. Only clustered columnstore index is updateable.
You can create clustered columnstore index in the Enterprise, Developer, and Evaluation editions and
once created a table cannot have any type of non-clustered index, unique constraints, primary key
constraints, or foreign key constraints.
If your table has a non-clustered columnstore index you can create unique constraints, primary key
constraints, or foreign key constraints, though the constraints cannot be included in the non-
clustered columnstore index.
To change definition of non-clustered columnstore index, you must drop and re-create the non-
clustered columnstore index instead; you cannot use ALTER INDEX statement. Though you can use
ALTER INDEX to disable and rebuild a columnstore index.
When creating non-clustered columnstore index you cannot include sparse columns and cannot use
INCLUDE or ASC or DESC clause.
When you create clustered columnstore index, the index itself contains the data whereas in the case
of non-clustered columnstore index, additional storage is required to store a copy of the columns in
the non-clustered columnstore index.
Clustered columnstore index cannot be combined with any other indexes (it’s the only index)
whereas in the case of non-clustered columnstore index you can create other indexes on the table as
well.
Columnstore index can be created on a temporary table.
Limitation and Restriction:
Cannot include Computed Column.
Cannot be created on a view or indexed view
Cannot include a sparse column
Cannot create on table have Trigger.
Cannot have more than 1024 columns
Database Administration Community (https://mostafaelmasry.wordpress.com)
A table with a nonclustered columnstore index can have unique constraints, primary key constraints,
or foreign key constraints, but the constraints cannot be included in the nonclustered columnstore
index
Cannot be changed by using the ALTER INDEX statement. To change the nonclustered index, you
must drop and re-create the columnstore index instead. You can useALTER INDEX to disable and
rebuild a columnstore index.
Cannot be created by using the INCLUDE keyword.
Cannot include the ASC or DESC keywords for sorting the index. Columnstore indexes are ordered
according to the compression algorithms. Sorting would eliminate many of the performance benefits. Data Types not Supported Clustered Column Store Index:
ntext, text, and image
varchar(max) and nvarchar(max)
rowversion (and timestamp)
hierarchyid , Sql_variant
XML
geography , geometry For more Information: CREATE COLUMNSTORE INDEX (Transact-SQL) , Clustered Columnstore Indexes
DEMO PART:
After I explained the basic information for Clustered column store index and the new improvement in
SQL Server 2014 in column store index and what is the limitation and which data type can be supported
this new type of index in SQL SERVER 2014 let’s go for the DEMO to know HOW WE CAN CREATE
CLUSTERED COLUMN STORE INDEX IN ONE CLICK: DOWNLOAD All Scripts Create CCI on ALL Tables on
my DEMO I used Database AdventureWorks2014 FOR DOWNLOAD .
In these scripts I will Support the below point:
Tables have Data type not supported clustered column store index .
Tables have computed columns or sparse columns.
Tables have already Clustered column Store index.
Tables have Trigger
List by Supported tables and Non Supported tables
Drop Foreign key for Supported Tables.
Drop Clustered and Non Clustered index on Supported tables.
Create Clustered Column Store index on all supported tables Our script has four parts and I will explain it one by one:
1. List by Supported tables and Non Supported tables (Download 1-SupportedNONSupportedTables)
2. Drop Foreign key for Supported Tables by the Rollback. (Download 2-DropForignKey)
3. Drop Clustered and Non Clustered index on Supported tables.(Download 3- Drop Clustered and Non
Clustered index)
4. Backup Index (not considered in this post ) but for information go for this POST
Database Administration Community (https://mostafaelmasry.wordpress.com)
5. Create Clustered Column Store index on all supported table (Download 4-
CreateClusteredColumnStoreIndex)]
List by Supported tables and Non Supported tables
Here is I saved all the tables tat’s have data types not supported CCI (Clustered column Store index) and
the tables have Computed columns , Sparse columns , tables have already CCI index after this i can
retrieve clearly TWO list
One by tables not supported CCI index and other one by tables Supported CCI index
Create PROC SupportedNONSupportedTables</pre> AS Set NOCOUNT on Begin ---Tables Not Supported CCI CREATE TABLE #tablesNotSupportedCCI ( TableName NVARCHAR(200), Typeofissue Nvarchar(200) ) Create Clustered Index [IX_#tablesNotSupportedCCI] on #tablesNotSupportedCCI (Tablename ASC) with(Fillfactor=80,Data_Compression=page) CREATE TABLE #SupportedTablesforCCI ( TABLEName NVARCHAR(200) ) Create Clustered Index [IX_#SupportedTablesforCCI] on #SupportedTablesforCCI (Tablename ASC) with(Fillfactor=80,Data_Compression=page) CREATE TABLE #CCI_DataType_Limitation ( DataType NVARCHAR(100) ) Create Clustered Index [IX_#CCI_DataType_Limitation] on #CCI_DataType_Limitation (DataType ASC) with(Fillfactor=80,Data_Compression=page) /* Data Type not supported by CCI Note : CCI not supported Nvarchar(MAX) and Vacrchar(MAX) but ididn't add it here becaue not data type = it as String */ INSERT INTO #CCI_DataType_Limitation VALUES ( 'text' ), ('Ntext'),
Database Administration Community (https://mostafaelmasry.wordpress.com)
('Image'), ( 'timestamp' ) , ( 'hierarchyid' ), ( 'Sql_variant' ), ( 'xml' ) , ( 'geography' ), ( 'geometry' ) ----Tables have columns wih data type not supported by CCI INSERT INTO #tablesNotSupportedCCI ( Tablename , Typeofissue ) SELECT distinct T.TABLE_NAME , 'DataType Not Supported by CCI' FROM INFORMATION_SCHEMA.TABLES T inner join INFORMATION_SCHEMA.COLUMNS C on C.TABLE_NAME = T.TABLE_NAME and T.TABLE_TYPE='BASE TABLE' where C.DATA_TYPE COLLATE SQL_Latin1_General_CP1_CI_AS IN ( SELECT DataType FROM #CCI_DataType_Limitation ) OR ( C.DATA_TYPE = 'nvarchar' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) OR ( C.DATA_TYPE = 'varchar' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) OR ( C.DATA_TYPE = 'varbinary' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) INSERT INTO #tablesNotSupportedCCI ( TableName,Typeofissue ) SELECT OBJECT_NAME(Object_ID) AS Tablename , 'Already have CCI' FROM Sys.indexes WHERE Type_desc = 'CLUSTERED COLUMNSTORE' ----Tables Have Trigger INSERT INTO #tablesNotSupportedCCI ( TableName , Typeofissue ) SELECT DISTINCT ( OBJECT_NAME([so].[parent_obj]) ) AS [table_name] , 'Trigger' FROM sysobjects AS [so] INNER JOIN sysobjects AS so2 ON so.parent_obj = so2.Id WHERE [so].[type] = 'TR'
Database Administration Community (https://mostafaelmasry.wordpress.com)
----tables have Computed_Column insert into #tablesNotSupportedCCI (Tablename,Typeofissue) Select T.name Table_Name , 'Computed_Column'from Sys.Columns AS C inner join Sys.tables As T on C.Object_Id = T.Object_Id where C.is_Computed =1 ----Tables have sparse columns insert into #tablesNotSupportedCCI (Tablename,Typeofissue) Select T.name Table_Name , 'Sparse_Column'from Sys.Columns AS C inner join Sys.tables As T on C.Object_Id = T.Object_Id where C.is_sparse =1 ----Supported Tables INSERT INTO #SupportedTablesforCCI ( TABLEName ) SELECT CONCAT(SC.name, '.', T.name) AS FullTableName FROM sys.tables AS T INNER JOIN Sys.schemas AS SC ON T.schema_id = SC.schema_id WHERE T.name COLLATE SQL_Latin1_General_CP1_CI_AS NOT IN ( SELECT Tablename FROM #tablesNotSupportedCCI ) Select TableName AS [Tables not supported CCI] , Typeofissue from #tablesNotSupportedCCI order by Typeofissue Select TableName AS [tables Supported CCI] from #SupportedTablesforCCI END
Drop foreign key for Supported Tables
After I listed all the tables Supported and Non Supported i will loop on all Supported tables to return the
Foreign key and the Constrain to save it temp tables then create the DML for Drooping Foreign key and
Rollback Create PROC DropForignKey AS Set NOCOUNT on Begin ---Tables Not Supported CCI CREATE TABLE #tablesNotSupportedCCI ( TableName NVARCHAR(200),
Database Administration Community (https://mostafaelmasry.wordpress.com)
Typeofissue Nvarchar(200) ) Create Clustered Index [IX_#tablesNotSupportedCCI] on #tablesNotSupportedCCI (Tablename ASC) with(Fillfactor=80,Data_Compression=page) CREATE TABLE #SupportedTablesforCCI ( TABLEName NVARCHAR(200) ) Create Clustered Index [IX_#SupportedTablesforCCI] on #SupportedTablesforCCI (Tablename ASC) with(Fillfactor=80,Data_Compression=page) CREATE TABLE #CCI_DataType_Limitation ( DataType NVARCHAR(100) ) Create Clustered Index [IX_#CCI_DataType_Limitation] on #CCI_DataType_Limitation (DataType ASC) with(Fillfactor=80,Data_Compression=page) CREATE TABLE #ForignKeys ( RowId INT PRIMARY KEY IDENTITY(1, 1), ForeignKeyConstraintName NVARCHAR(200), ForeignKeyConstraintTableSchema NVARCHAR(200), ForeignKeyConstraintTableName NVARCHAR(200), ForeignKeyConstraintColumnName NVARCHAR(200), PrimaryKeyConstraintName NVARCHAR(200), PrimaryKeyConstraintTableSchema NVARCHAR(200), PrimaryKeyConstraintTableName NVARCHAR(200), PrimaryKeyConstraintColumnName NVARCHAR(200) ) INSERT INTO #CCI_DataType_Limitation VALUES ( 'text' ), ('Ntext'), ('Image'), ( 'timestamp' ) , ( 'hierarchyid' ), ( 'Sql_variant' ), ( 'xml' ) , ( 'geography' ), ( 'geometry' ) ----Tables have columns wih data type not supported by CCI INSERT INTO #tablesNotSupportedCCI ( Tablename , Typeofissue )
Database Administration Community (https://mostafaelmasry.wordpress.com)
SELECT distinct T.TABLE_NAME , 'DataType Not Supported by CCI' FROM INFORMATION_SCHEMA.TABLES T inner join INFORMATION_SCHEMA.COLUMNS C on C.TABLE_NAME = T.TABLE_NAME and T.TABLE_TYPE='BASE TABLE' where C.DATA_TYPE COLLATE SQL_Latin1_General_CP1_CI_AS IN ( SELECT DataType FROM #CCI_DataType_Limitation ) OR ( C.DATA_TYPE = 'nvarchar' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) OR ( C.DATA_TYPE = 'varchar' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) OR ( C.DATA_TYPE = 'varbinary' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) INSERT INTO #tablesNotSupportedCCI ( TableName,Typeofissue ) SELECT OBJECT_NAME(Object_ID) AS Tablename , 'Already have CCI' FROM Sys.indexes WHERE Type_desc = 'CLUSTERED COLUMNSTORE' ----Tables Have Trigger INSERT INTO #tablesNotSupportedCCI ( TableName , Typeofissue ) SELECT DISTINCT ( OBJECT_NAME([so].[parent_obj]) ) AS [table_name] , 'Trigger' FROM sysobjects AS [so] INNER JOIN sysobjects AS so2 ON so.parent_obj = so2.Id WHERE [so].[type] = 'TR' ----tables have Computed_Column insert into #tablesNotSupportedCCI (Tablename,Typeofissue) Select T.name Table_Name , 'Computed_Column'from Sys.Columns AS C inner join Sys.tables As T on C.Object_Id = T.Object_Id where C.is_Computed =1 ----Tables have sparse columns insert into #tablesNotSupportedCCI (Tablename,Typeofissue) Select T.name Table_Name , 'Sparse_Column'from Sys.Columns AS C
Database Administration Community (https://mostafaelmasry.wordpress.com)
inner join Sys.tables As T on C.Object_Id = T.Object_Id where C.is_sparse =1 ----Supported Tables INSERT INTO #SupportedTablesforCCI ( TABLEName ) SELECT CONCAT(SC.name, '.', T.name) AS FullTableName FROM sys.tables AS T INNER JOIN Sys.schemas AS SC ON T.schema_id = SC.schema_id WHERE T.name COLLATE SQL_Latin1_General_CP1_CI_AS NOT IN ( SELECT Tablename FROM #tablesNotSupportedCCI ) -------Dropping the Forign KEYS for the Tables Supported by CCI INSERT INTO #ForignKeys(ForeignKeyConstraintName, ForeignKeyConstraintTableSchema, ForeignKeyConstraintTableName, ForeignKeyConstraintColumnName) SELECT U.CONSTRAINT_NAME, U.TABLE_SCHEMA, U.TABLE_NAME, U.COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE U INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C ON U.CONSTRAINT_NAME = C.CONSTRAINT_NAME WHERE C.CONSTRAINT_TYPE = 'FOREIGN KEY' UPDATE #ForignKeys SET PrimaryKeyConstraintName = UNIQUE_CONSTRAINT_NAME COLLATE SQL_Latin1_General_CP1256_CI_AS FROM #ForignKeys T INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R ON T.ForeignKeyConstraintName = R.CONSTRAINT_NAME COLLATE SQL_Latin1_General_CP1256_CI_AS UPDATE #ForignKeys SET PrimaryKeyConstraintTableSchema = TABLE_SCHEMA, PrimaryKeyConstraintTableName = TABLE_NAME FROM #ForignKeys T INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C ON T.PrimaryKeyConstraintName = C.CONSTRAINT_NAME COLLATE SQL_Latin1_General_CP1256_CI_AS UPDATE #ForignKeys SET PrimaryKeyConstraintColumnName = COLUMN_NAME FROM #ForignKeys T
Database Administration Community (https://mostafaelmasry.wordpress.com)
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE U ON T.PrimaryKeyConstraintName = U.CONSTRAINT_NAME COLLATE SQL_Latin1_General_CP1256_CI_AS SELECT ' ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + '] DROP CONSTRAINT ' + ForeignKeyConstraintName + ' GO' AS DropCONSTRAINT FROM #ForignKeys WHERE CONCAT(ForeignKeyConstraintTableSchema COLLATE SQL_Latin1_General_CP1256_CI_AS,'.',ForeignKeyConstraintTableName COLLATE SQL_Latin1_General_CP1256_CI_AS) IN (SELECT TABLEName FROM #SupportedTablesforCCI) -----ADD CONSTRAINT: SELECT ' ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + '] ADD CONSTRAINT ' + ForeignKeyConstraintName + ' FOREIGN KEY(' + ForeignKeyConstraintColumnName + ') REFERENCES [' + PrimaryKeyConstraintTableSchema + '].[' + PrimaryKeyConstraintTableName + '](' + PrimaryKeyConstraintColumnName + ') GO' AS ADDCONSTRAINT FROM #ForignKeys WHERE CONCAT(ForeignKeyConstraintTableSchema COLLATE SQL_Latin1_General_CP1256_CI_AS,'.',ForeignKeyConstraintTableName COLLATE SQL_Latin1_General_CP1256_CI_AS) IN (SELECT TABLEName FROM #SupportedTablesforCCI) DROP TABLE #SupportedTablesforCCI DROP TABLE #CCI_DataType_Limitation DROP TABLE #tablesNotSupportedCCI Drop table #ForignKeys END Drop Clustered and Non Clustered index on Supported tables After I listed all the tables Supported and Non Supported and dropping the foreign key I will loop on all Supported tables to return the Clustered and Non Clustered index to save it temp tables then create the DML for Drooping Clustered and Non Clustered Index for the Rollback check this POST Create PROC Dropindex AS Set NOCOUNT on Begin
Database Administration Community (https://mostafaelmasry.wordpress.com)
---Tables Not Supported CCI CREATE TABLE #tablesNotSupportedCCI ( TableName NVARCHAR(200), Typeofissue Nvarchar(200) ) Create Clustered Index [IX_#tablesNotSupportedCCI] on #tablesNotSupportedCCI (Tablename ASC) with(Fillfactor=80,Data_Compression=page) CREATE TABLE #SupportedTablesforCCI ( TABLEName NVARCHAR(200) ) Create Clustered Index [IX_#SupportedTablesforCCI] on #SupportedTablesforCCI (Tablename ASC) with(Fillfactor=80,Data_Compression=page) CREATE TABLE #CCI_DataType_Limitation ( DataType NVARCHAR(100) ) Create Clustered Index [IX_#CCI_DataType_Limitation] on #CCI_DataType_Limitation (DataType ASC) with(Fillfactor=80,Data_Compression=page) INSERT INTO #CCI_DataType_Limitation VALUES ( 'text' ), ('Ntext'), ('Image'), ( 'timestamp' ) , ( 'hierarchyid' ), ( 'Sql_variant' ), ( 'xml' ) , ( 'geography' ), ( 'geometry' ) ----Tables have columns wih data type not supported by CCI INSERT INTO #tablesNotSupportedCCI ( Tablename , Typeofissue ) SELECT distinct T.TABLE_NAME , 'DataType Not Supported by CCI' FROM INFORMATION_SCHEMA.TABLES T inner join INFORMATION_SCHEMA.COLUMNS C on C.TABLE_NAME = T.TABLE_NAME and T.TABLE_TYPE='BASE TABLE' where C.DATA_TYPE COLLATE SQL_Latin1_General_CP1_CI_AS IN ( SELECT DataType FROM #CCI_DataType_Limitation )
Database Administration Community (https://mostafaelmasry.wordpress.com)
OR ( C.DATA_TYPE = 'nvarchar' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) OR ( C.DATA_TYPE = 'varchar' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) OR ( C.DATA_TYPE = 'varbinary' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) INSERT INTO #tablesNotSupportedCCI ( TableName,Typeofissue ) SELECT OBJECT_NAME(Object_ID) AS Tablename , 'Already have CCI' FROM Sys.indexes WHERE Type_desc = 'CLUSTERED COLUMNSTORE' ----Tables Have Trigger INSERT INTO #tablesNotSupportedCCI ( TableName , Typeofissue ) SELECT DISTINCT ( OBJECT_NAME([so].[parent_obj]) ) AS [table_name] , 'Trigger' FROM sysobjects AS [so] INNER JOIN sysobjects AS so2 ON so.parent_obj = so2.Id WHERE [so].[type] = 'TR' ----tables have Computed_Column insert into #tablesNotSupportedCCI (Tablename,Typeofissue) Select T.name Table_Name , 'Computed_Column'from Sys.Columns AS C inner join Sys.tables As T on C.Object_Id = T.Object_Id where C.is_Computed =1 ----Tables have sparse columns insert into #tablesNotSupportedCCI (Tablename,Typeofissue) Select T.name Table_Name , 'Sparse_Column'from Sys.Columns AS C inner join Sys.tables As T on C.Object_Id = T.Object_Id where C.is_sparse =1 ----Supported Tables INSERT INTO #SupportedTablesforCCI ( TABLEName ) SELECT CONCAT(SC.name, '.', T.name) AS FullTableName
Database Administration Community (https://mostafaelmasry.wordpress.com)
FROM sys.tables AS T INNER JOIN Sys.schemas AS SC ON T.schema_id = SC.schema_id WHERE T.name COLLATE SQL_Latin1_General_CP1_CI_AS NOT IN ( SELECT Tablename FROM #tablesNotSupportedCCI ) ---Dropping Clustered and Non Clustered index for the Tables Supported by CCI DECLARE @indexName NVARCHAR(128) DECLARE @dropIndexSql NVARCHAR(4000) DECLARE @TableName NVARCHAR(4000) DECLARE @NewLineChar AS CHAR(2) = CHAR(13) + CHAR(10) DECLARE TableList CURSOR FOR SELECT TABLEName FROM #SupportedTablesforCCI OPEN TableList FETCH NEXT FROM TableList INTO @TableName WHILE @@fetch_status = 0 BEGIN DECLARE tableIndexes CURSOR FOR SELECT name FROM sysindexes WHERE id = OBJECT_ID(@TableName) AND indid > 0 AND indid < 255 AND INDEXPROPERTY(id, name, 'IsStatistics') = 0 ORDER BY indid DESC OPEN tableIndexes FETCH NEXT FROM tableIndexes INTO @indexName WHILE @@fetch_status = 0 BEGIN IF LEFT(@IndexName, 2) = 'PK' BEGIN PRINT ( 'ALTER TABLE ' + @TableName + ' DROP CONSTRAINT ' + @IndexName + @NewLineChar + 'GO' ) END ELSE BEGIN SET @dropIndexSql = N'DROP INDEX ' + @indexName + ' On ' + @TableName + @NewLineChar + 'GO'
Database Administration Community (https://mostafaelmasry.wordpress.com)
PRINT @dropIndexSql END FETCH NEXT FROM tableIndexes INTO @indexName END CLOSE tableIndexes DEALLOCATE tableIndexes FETCH NEXT FROM TableList INTO @TableName END CLOSE TableList DEALLOCATE TableList DROP TABLE #SupportedTablesforCCI DROP TABLE #CCI_DataType_Limitation DROP TABLE #tablesNotSupportedCCI END Create Clustered Column Store index on all supported table
Final Step after I do everything for checking the tables and filtered it based on what can support CCI and
what cannot support then dropping the foreign key, constrain, clustered index and non-Clustered index
our tables now ready for creating Column Store index this script is Sufficient for the purpose and
comprehensive all the previous pasts
Create Procedure CreateClusteredColumnStoreIndex AS Set NOCOUNT on Begin ---Tables Not Supported CCI CREATE TABLE #tablesNotSupportedCCI ( TableName NVARCHAR(200), Typeofissue Nvarchar(200) ) Create Clustered Index [IX_#tablesNotSupportedCCI] on #tablesNotSupportedCCI (Tablename ASC) with(Fillfactor=80,Data_Compression=page) CREATE TABLE #SupportedTablesforCCI ( TABLEName NVARCHAR(200) ) Create Clustered Index [IX_#SupportedTablesforCCI] on #SupportedTablesforCCI (Tablename ASC) with(Fillfactor=80,Data_Compression=page) CREATE TABLE #CCI_DataType_Limitation ( DataType NVARCHAR(100)
Database Administration Community (https://mostafaelmasry.wordpress.com)
) Create Clustered Index [IX_#CCI_DataType_Limitation] on #CCI_DataType_Limitation (DataType ASC) with(Fillfactor=80,Data_Compression=page) CREATE TABLE #ForignKeys ( RowId INT PRIMARY KEY IDENTITY(1, 1), ForeignKeyConstraintName NVARCHAR(200), ForeignKeyConstraintTableSchema NVARCHAR(200), ForeignKeyConstraintTableName NVARCHAR(200), ForeignKeyConstraintColumnName NVARCHAR(200), PrimaryKeyConstraintName NVARCHAR(200), PrimaryKeyConstraintTableSchema NVARCHAR(200), PrimaryKeyConstraintTableName NVARCHAR(200), PrimaryKeyConstraintColumnName NVARCHAR(200) ) /* Data Type not supported by CCI Note : CCI not supported Nvarchar(MAX) and Vacrchar(MAX) but ididn't add it here becaue not data type = it as String */ INSERT INTO #CCI_DataType_Limitation VALUES ( 'text' ), ('Ntext'), ('Image'), ( 'timestamp' ) , ( 'hierarchyid' ), ( 'Sql_variant' ), ( 'xml' ) , ( 'geography' ), ( 'geometry' ) ----Tables have columns wih data type not supported by CCI INSERT INTO #tablesNotSupportedCCI ( Tablename , Typeofissue ) SELECT distinct T.TABLE_NAME , 'DataType Not Supported by CCI' FROM INFORMATION_SCHEMA.TABLES T inner join INFORMATION_SCHEMA.COLUMNS C on C.TABLE_NAME = T.TABLE_NAME and T.TABLE_TYPE='BASE TABLE' where C.DATA_TYPE COLLATE SQL_Latin1_General_CP1_CI_AS IN ( SELECT DataType FROM #CCI_DataType_Limitation ) OR ( C.DATA_TYPE = 'nvarchar'
Database Administration Community (https://mostafaelmasry.wordpress.com)
AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) OR ( C.DATA_TYPE = 'varchar' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) OR ( C.DATA_TYPE = 'varbinary' AND C.CHARACTER_MAXIMUM_LENGTH = '-1' ) -------- INSERT INTO #tablesNotSupportedCCI ( TableName,Typeofissue ) SELECT OBJECT_NAME(Object_ID) AS Tablename , 'Already have CCI' FROM Sys.indexes WHERE Type_desc = 'CLUSTERED COLUMNSTORE' ----Tables Have Trigger INSERT INTO #tablesNotSupportedCCI ( TableName , Typeofissue ) SELECT DISTINCT ( OBJECT_NAME([so].[parent_obj]) ) AS [table_name] , 'Trigger' FROM sysobjects AS [so] INNER JOIN sysobjects AS so2 ON so.parent_obj = so2.Id WHERE [so].[type] = 'TR' ----tables have Computed_Column insert into #tablesNotSupportedCCI (Tablename,Typeofissue) Select T.name Table_Name , 'Computed_Column'from Sys.Columns AS C inner join Sys.tables As T on C.Object_Id = T.Object_Id where C.is_Computed =1 ----Tables have sparse columns insert into #tablesNotSupportedCCI (Tablename,Typeofissue) Select T.name Table_Name , 'Sparse_Column'from Sys.Columns AS C inner join Sys.tables As T on C.Object_Id = T.Object_Id where C.is_sparse =1 ----Supported Tables INSERT INTO #SupportedTablesforCCI ( TABLEName ) SELECT CONCAT(SC.name, '.', T.name) AS FullTableName
Database Administration Community (https://mostafaelmasry.wordpress.com)
FROM sys.tables AS T INNER JOIN Sys.schemas AS SC ON T.schema_id = SC.schema_id WHERE T.name COLLATE SQL_Latin1_General_CP1_CI_AS NOT IN ( SELECT Tablename FROM #tablesNotSupportedCCI ) Select TableName AS [Tables not supported CCI] , Typeofissue from #tablesNotSupportedCCI order by Typeofissue Select TableName AS [tables Supported CCI] from #SupportedTablesforCCI -------Dropping the Forign KEYS for the Tables Supported by CCI INSERT INTO #ForignKeys(ForeignKeyConstraintName, ForeignKeyConstraintTableSchema, ForeignKeyConstraintTableName, ForeignKeyConstraintColumnName) SELECT U.CONSTRAINT_NAME, U.TABLE_SCHEMA, U.TABLE_NAME, U.COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE U INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C ON U.CONSTRAINT_NAME = C.CONSTRAINT_NAME WHERE C.CONSTRAINT_TYPE = 'FOREIGN KEY' UPDATE #ForignKeys SET PrimaryKeyConstraintName = UNIQUE_CONSTRAINT_NAME COLLATE SQL_Latin1_General_CP1256_CI_AS FROM #ForignKeys T INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R ON T.ForeignKeyConstraintName = R.CONSTRAINT_NAME COLLATE SQL_Latin1_General_CP1256_CI_AS UPDATE #ForignKeys SET PrimaryKeyConstraintTableSchema = TABLE_SCHEMA, PrimaryKeyConstraintTableName = TABLE_NAME FROM #ForignKeys T INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C ON T.PrimaryKeyConstraintName = C.CONSTRAINT_NAME COLLATE SQL_Latin1_General_CP1256_CI_AS UPDATE #ForignKeys SET PrimaryKeyConstraintColumnName = COLUMN_NAME FROM #ForignKeys T INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE U ON T.PrimaryKeyConstraintName = U.CONSTRAINT_NAME COLLATE SQL_Latin1_General_CP1256_CI_AS SELECT '
Database Administration Community (https://mostafaelmasry.wordpress.com)
ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + '] DROP CONSTRAINT ' + ForeignKeyConstraintName + ' GO' AS DropCONSTRAINT FROM #ForignKeys WHERE CONCAT(ForeignKeyConstraintTableSchema COLLATE SQL_Latin1_General_CP1256_CI_AS,'.',ForeignKeyConstraintTableName COLLATE SQL_Latin1_General_CP1256_CI_AS) IN (SELECT TABLEName FROM #SupportedTablesforCCI) -----ADD CONSTRAINT: SELECT ' ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + '] ADD CONSTRAINT ' + ForeignKeyConstraintName + ' FOREIGN KEY(' + ForeignKeyConstraintColumnName + ') REFERENCES [' + PrimaryKeyConstraintTableSchema + '].[' + PrimaryKeyConstraintTableName + '](' + PrimaryKeyConstraintColumnName + ') GO' AS ADDCONSTRAINT FROM #ForignKeys WHERE CONCAT(ForeignKeyConstraintTableSchema COLLATE SQL_Latin1_General_CP1256_CI_AS,'.',ForeignKeyConstraintTableName COLLATE SQL_Latin1_General_CP1256_CI_AS) IN (SELECT TABLEName FROM #SupportedTablesforCCI) ---Dropping Clustered and Non Clustered index for the Tables Supported by CCI DECLARE @indexName NVARCHAR(128) DECLARE @dropIndexSql NVARCHAR(4000) DECLARE @TableName NVARCHAR(4000) DECLARE @NewLineChar AS CHAR(2) = CHAR(13) + CHAR(10) DECLARE TableList CURSOR FOR SELECT TABLEName FROM #SupportedTablesforCCI OPEN TableList FETCH NEXT FROM TableList INTO @TableName WHILE @@fetch_status = 0 BEGIN DECLARE tableIndexes CURSOR FOR SELECT name
Database Administration Community (https://mostafaelmasry.wordpress.com)
FROM sysindexes WHERE id = OBJECT_ID(@TableName) AND indid > 0 AND indid < 255 AND INDEXPROPERTY(id, name, 'IsStatistics') = 0 ORDER BY indid DESC OPEN tableIndexes FETCH NEXT FROM tableIndexes INTO @indexName WHILE @@fetch_status = 0 BEGIN IF LEFT(@IndexName, 2) = 'PK' BEGIN PRINT ( 'ALTER TABLE ' + @TableName + ' DROP CONSTRAINT ' + @IndexName + @NewLineChar + 'GO' ) END ELSE BEGIN SET @dropIndexSql = N'DROP INDEX ' + @indexName + ' On ' + @TableName + @NewLineChar + 'GO' PRINT @dropIndexSql END FETCH NEXT FROM tableIndexes INTO @indexName END CLOSE tableIndexes DEALLOCATE tableIndexes FETCH NEXT FROM TableList INTO @TableName END CLOSE TableList DEALLOCATE TableList -----CRRETE CLUSTERD COLUMNSTORE INDEX DECLARE @SQL NVARCHAR(MAX) DECLARE @table NVARCHAR(200) DECLARE vend_cursor CURSOR FOR Select tablename from #SupportedTablesforCCI OPEN vend_cursor FETCH NEXT FROM vend_cursor INTO @table WHILE @@FETCH_STATUS = 0
Database Administration Community (https://mostafaelmasry.wordpress.com)
BEGIN SET @SQL = 'CREATE CLUSTERED COLUMNSTORE INDEX [ClusteredColumnStoreIndex-' + @table + '] ON ' + @table + ' WITH (DROP_EXISTING = OFF)' + @NewLineChar + 'GO' --Execute Sp_ExecuteSQL @SQL PRINT @SQL FETCH NEXT FROM vend_cursor INTO @table END CLOSE vend_cursor DEALLOCATE vend_cursor DROP TABLE #SupportedTablesforCCI DROP TABLE #CCI_DataType_Limitation DROP TABLE #tablesNotSupportedCCI Drop table #ForignKeys END Really this scripts is very useful and important for any need to go for crating Clustered column store
index on multiple tables
Follow the author: View all my tips , LinkedIn , Website , Slideshare