|sp_indexinfo - enhanced index information procedure|
About me and Nucleus
Articles, tips etc.
Courses and training
I often find myself wanting to know lots about the indexes for a table or for all tables in a database. This is why I wrote sp_indexinfo.
This script was written for SQL Server 2008 or later. If you want to run it on 2005 you will have to comment out at least the i.filter_definition column from the first SELECT statement, possibly some other columns.
Article written: 2008-07-07
Article last modified: See change log at end of this page.
I can't count how many times I wanted to know more about physical attributes for a table, including index information. So I end up running sp_helpindex, some SELECT over sys.indexes, some reports in SSMS, some other queries against other catalog and dynamic management views, etc. I wrote this procedure for those cases. Here's my version of a procedure to give me information like:
I frequently spend lots of time in one particular database, and I then would want to "post-process" the result from a procedure like this. By "post-process" I mean things like sorting and grouping. I suggest that you for those cases take the first SELECT statement and create a view out of it. You can now SELECT from this view with any ORDER BY, GROUP BY, aggregate function etc as you wish. Start with the row starting with WITH and end before the "AND OBJECT_NAME(i.OBJECT_ID) LIKE @tblPat" row. For instance, I created such a view (I named the view index_info) in one of my databases and below are some queries I ran against this view:
Name of table. Default is all tables in current database.
Whether or not to include missing indexes information. Default is 0 (no).
Below is brief documentation of what the procedure returns. Note that the procedure only uses documented sources (catalog views, functions etc.). So for deeper documentation I suggest you check the SQL Server Books Online for sys.indexes, sys.partitions etc. (see the source code for the procedure).
First resultset, index information
Second resultset, missing index information. This is recommended indexes according to the optimizer. When the optimizer work a query, it can notice "obvious" indexes to add. I do not suggest you follow these blindly. They might, however, pick up things you missed. This informationis picked up from the sys.dm_db_missing_index DMV's. See SQL Server Books Online for deeper information.
You find the code here.
Added missing index information controlled by optional parameter.
Added schema name in first resultset.
Added 'DESC' for descending keys, tip from Alejandro Mesa.
Added COALESCE for included columns so the whole CREATE INDEX isn't NULL for missing index recommendation where no included columns are recommended. Caught by Aaron Bertrand.
Restricted missing index recommendation to current database. Caught by Aaron Bertrand.
Added parenthesis around key columns in the generated CREATE INDEX command, in the missing indexes resultset.
Fixed so that a comma is introduced in the generated CREATE TABLE if both equality as well as inequality columns are recommended. Thanks to Razvan Socol.
Made key_columns and included_columns a bit nicer by removing ending ', '.
Included XML indexes. I have not, however considered adding information for space usage for these "indexes". XML indexes are not regular b-tree indexes so space usage info is found elsewhere. And I still want to keep this in one query (not procedural code). Perhaps some slow day I will look at adding spae usage info for XML indexes, but not today. :-)
Thanks to Dejan Sarka for above two tips.
Added brief documentation of what the procedure returns.
Added filtered index, as suggested by at my blog by Lidong (thanks!).
Added explicit text to indicate if index is disabled. Thanks to Henrik Staun Poulsen.
Added calls to INDEXPROPERTY to check if index is disabled, depth, fillfactor etc. This new code is commented, remove comments as you wish. Thanks to Stephen Morris.
Fixed a bug where row count could be doubled or trippled if LOB data exists and/or row overflow data. Thanks JackMcC, reporing this here.
Changed last query to generate the index name. This is based on schema name, object name, and each column name - truncated to 128 characters.
Re-arranged and shortened column names to make output more compact and more commonly used column moved to the right.
Uncommented some columns that were previously commented.
Added support for columnstore indexes.
Added compression column, as per Stephen Morris' suggestion.