Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « Stripping rows out of file importsDo you use Column=@Param OR @Param IS NULL in your WHERE clause? Don't, it doesn't perform »
    comments

    There are certain operations where dropping an index, loading data and then again creating the index can speed up data loading. SQL server 2005 introduced a way to disable an index.

    Let's take a look, first create this table

    1. Create table TestIndex (id int, somecol varchar(20))


    Insert a little bit of data

    1. insert into TestIndex
    2.   select number,CONVERT(varchar(20),getdate(),100)
    3.   from master..spt_values
    4.   where type = 'p'


    Create a nonclustered index

    1. create index ix_TestIndex on TestIndex(id,somecol)


    Now let's disable this index

    1. ALTER INDEX ix_TestIndex
    2.   ON TestIndex
    3.   DISABLE


    Now when we run our query against the table and look at the plan we get a table scan

    1. set showplan_text on
    2.   go
    3.   select * from TestIndex
    4.   go
    5.   set showplan_text off
    6.   go
        |--Table Scan(OBJECT:([master].[dbo].[TestIndex]))
        
        

    Now let's rebuild the index again

    1. ALTER INDEX ix_TestIndex
    2.   ON TestIndex
    3.   REBUILD



    Now we will run the same query again

    1. set showplan_text on
    2.   go
    3.   select * from TestIndex
    4.   go
    5.   set showplan_text off
    6.   go
     
       |--Index Scan(OBJECT:([master].[dbo].[TestIndex].[ix_TestIndex]))
        

    As you can see, it uses the index again

    Now let's drop this index

    1. drop index TestIndex.ix_TestIndex





    Is there a difference how disable works between nonclustered and clustered indexes?
    Let's take a look, first create this clustered index

    1. create clustered index ix_TestIndexClustered on TestIndex(id,somecol)


    Now let's disable this clustered index

    1. ALTER INDEX ix_TestIndexClustered
    2.   ON TestIndex
    3.   DISABLE


    And now when we run the query from before

    1. set showplan_text on
    2.   go
    3.   select * from TestIndex
    4.   go
    5.   set showplan_text off
    6.   go


    We get this error
    Msg 8655, Level 16, State 1, Line 1
    The query processor is unable to produce a plan because the index 'ix_TestIndexClustered' on table or view 'TestIndex' is disabled.

    As you can see while a clustered index is disabled the data is unavailable. Not only that, you can also not insert anything into the table,
    So this query

    1. insert into TestIndex
    2. select 2,'Bla'


    Fails with the same error from before
    Msg 8655, Level 16, State 1, Line 1
    The query processor is unable to produce a plan because the index 'ix_TestIndexClustered' on table or view 'TestIndex' is disabled.


    If we rebuild the clustered index again

    1. ALTER INDEX ix_TestIndexClustered
    2.   ON TestIndex
    3.   REBUILD



    And if we run this query again

    1. set showplan_text on
    2.   go
    3.   select * from TestIndex
    4.   go
    5.   set showplan_text off
    6.   go
      |--Clustered Index Scan(OBJECT:([master].[dbo].[TestIndex].[ix_TestIndexClustered]))


    We can see that it does use the clustered index

    My question to you.
    So my question to you people is, do any of you use this instead of drop and create index? One advantage I see is that you don't need to update the code that drops and recreates the non clustered index if your index definition changes when using disable index in your ETL process. If you disable a clustered index you can also not insert into the table.




    *** Remember, if you have a SQL related question, try our Microsoft SQL Server Programming forum or our Microsoft SQL Server Admin forum

    About the Author

    User bio imageDenis has been working with SQL Server since version 6.5. Although he worked as an ASP/JSP/ColdFusion developer before the dot com bust, he has been working exclusively as a database developer/architect since 2002. In addition to English, Denis is also fluent in Croatian and Dutch, but he can curse in many other languages and dialects (just ask the SQL optimizer) He lives in Princeton, NJ with his wife and three kids.
    Social SitingsTwitterFacebookLinkedInHomePageFlickrLTD RSS Feed
    3327 views
    Instapaper

    No feedback yet

    Leave a comment


    Your email address will not be revealed on this site.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)