21
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

Create column store index on all supported tables in sql server 2014 copy

Embed Size (px)

Citation preview

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