sql-serversql-server-2008indexingsql-server-2008-r2sqlperformance

Should every User Table have a Clustered Index?


Recently I found a couple of tables in a Database with no Clustered Indexes defined. But there are non-clustered indexes defined, so they are on HEAP.

On analysis I found that select statements were using filter on the columns defined in non-clustered indexes.

Not having a clustered index on these tables affect performance?


Solution

  • It's hard to state this more succinctly than SQL Server MVP Brad McGehee:

    As a rule of thumb, every table should have a clustered index. Generally, but not always, the clustered index should be on a column that monotonically increases–such as an identity column, or some other column where the value is increasing–and is unique. In many cases, the primary key is the ideal column for a clustered index.

    BOL echoes this sentiment:

    With few exceptions, every table should have a clustered index.

    The reasons for doing this are many and are primarily based upon the fact that a clustered index physically orders your data in storage.

    You may not want to have a clustered index on:

    Because of these and other considerations, such as your particular application workloads, you should carefully select your clustered indexes to get maximum benefit for your queries.

    Also note that when you create a primary key on a table in SQL Server, it will by default create a unique clustered index (if it doesn't already have one). This means that if you find a table that doesn't have a clustered index, but does have a primary key (as all tables should), a developer had previously made the decision to create it that way. You may want to have a compelling reason to change that (of which there are many, as we've seen). Adding, changing or dropping the clustered index requires rewriting the entire table and any non-clustered indexes, so this can take some time on a large table.