Tuning Enovia SmarTeam - Indexes - Conclusion

[Prior Post in Series] [Next Post in Series]

In this part, I will deal with the fact that many remaining tables do not have clustered indexes on them. In my humble opinion, ANY reasonable order of the disk will perform better than a random order, so putting a clustered index on every table is a must-do.

The pattern is simple, if a table does not have a clustered index, then put a clustered index on the first column. The typical behavior of database designers is to put the key indexes at the start of each table, so we are assuming this is true in this solution.

To obtain the list of tables lacking indexes, use this code snippet.

 

 SELECT O.NAME FROM Sys.Objects O 
WHERE  O.type='U'
AND O.Name NOT IN (
SELECT O.Name FROM Sys.Objects O 
JOIN Sys.Indexes I 
ON I.Object_Id=O.Object_Id 
AND O.type='U' 
AND I.type_desc='CLUSTERED')

You may wish to manually add some indexes (based on your domain knowledge) before proceeding further.

Code Solution

The solution below grabs the first column only. A more advanced approach would be to walk each table and build the index from the leading columns that are integer values.

 SET NOCOUNT ON
DECLARE @CMD nvarchar(max)
DECLARE @Schema nvarchar(max)
DECLARE @Table nvarchar(max)
DECLARE @ColName nvarchar(max)

DECLARE PK_Cursor CURSOR FOR
Select o.Table_Schema, O.Table_Name, O.Column_Name
    FROM Information_Schema.Columns O
    JOIN Information_Schema.Tables T
        ON O.Table_Name=T.Table_Name
        AND O.Table_Schema=T.Table_Schema 
    WHERE O.Ordinal_Position=1
        AND T.Table_Type='BASE TABLE'
        AND O.Table_Name NOT IN (
    SELECT O.Name FROM Sys.Objects O 
        JOIN Sys.Indexes I 
            ON I.Object_Id=O.Object_Id 
            AND O.type='U' 
            AND I.type_desc='CLUSTERED')
    ORDER BY O.Column_NAME

OPEN PK_Cursor;
FETCH NEXT FROM PK_Cursor INTO @Schema,@Table,@ColName
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @CMD='CREATE CLUSTERED INDEX [PK_'
    +@TABLE+'] ON ['+@Schema+'].['+@Table+'](['+@ColName+'] ASC)'
    IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE Name='PK_'+@Table)
    BEGIN TRY
        EXEC (@CMD)
    END TRY
    BEGIN CATCH
        SET @CMD='Error: '+@CMD
        Print @CMD
    END CATCH
    FETCH NEXT FROM PK_Cursor INTO @Schema,@Table,@ColName
END;
CLOSE PK_Cursor;
DEALLOCATE PK_Cursor;

Summary

In this post we looked at loose-ends: tables lacking any clustered indexes. We solved this problem by adding a clustered index using the first column. A lot more analysis could be done on this database, but I ran out of time (after an apparent doubling of performance).