March 9, 2020 at 5:30 pm
Is there a way to generate only the indexes for an entire DB. If I right click the DB and go to tasks>Generate scripts I can check create indexes but I always get the tables from Advanced option, so i just need all indexes with drop and create statement without table script. The reason I'm needing only the indexes is we are migrating from non SQL Server DB to SQL Server and we are using SSIS packages. With a fast load in the package the data transfer is extremely fast with no indexes but slower when indexes exists are the target tables. So after the data move we want to then apply all the required indexes.
March 9, 2020 at 7:20 pm
Create the indexes as you need them in SQL Server. You can then disable the NC indexes prior to loading the data - and rebuild the indexes after the data has been loaded.
Create Procedure [dbo].[disableNCIndexes]
@objectName sysname -- include Schema in objectName (e.g. dbo.Table)
As
/* ===========================================================================================
Author: Jeff Williams
Created: 08/24/2017
Description: Disables all Non-Clustered indexes for the specified object/table
This procedure is used during load processes to disable the non-clustered
indexes on the object. This can improve performance for the load process
when you are loading a smaller subset of data into a very large table or
when you have lots of indexes with multiple columns included.
If you utilize this procedure - you then need to rebuild all indexes once
the data has been loaded using ALTER INDEX ALL ON {object} REBUILD;
Called From:
SSIS or load procedures
Example Call:
Execute dbo.disableNCIndexes @objectName = 'supermart.v_demographic_denorm';
Revision History
Date Edited By Change
---------- --------------- --------------------------------------------------------------
08/24/2017 Jeff Williams Created
=========================================================================================== */
Set Nocount On;
Declare @objectId int
, @indexName sysname
, @schemaName sysname
, @command nvarchar(max);
Set @objectId = object_id(@objectName);
--==== Loop through indexes for this object
Declare indexes Cursor Local Static
For
Select o.Name As ObjectName
, object_schema_name(o.[object_id]) As SchemaName
, i.Name As IndexName
From sys.objects o
Inner Join sys.indexes i On i.object_id = o.object_id
Where o.type = 'U'
And i.index_id > 1
And o.object_id = @objectId;
Open indexes;
Fetch Next From indexes Into @objectName, @schemaName, @indexName;
While @@fetch_status = 0
Begin;
--==== Build and execute the command to disable the index
Set @command = concat('ALTER INDEX ', quotename(@indexName), ' ON ', quotename(@schemaName), '.', quotename(@objectName), ' DISABLE;');
Execute sp_executeSql @command; Print 'Executed: ' + @command;
Fetch Next From indexes Into @objectName, @schemaName, @indexName;
End;
--==== Close/Deallocate the cursor
Close indexes;
Deallocate indexes;
After the load has completed - rebuild the indexes:
ALTER INDEX ALL ON dbo.MyTable REBUILD;
Jeffrey Williams
“We are all faced with a series of great opportunities brilliantly disguised as impossible situations.”
― Charles R. Swindoll
How to post questions to get better answers faster
Managing Transaction Logs
March 9, 2020 at 10:29 pm
Thanks! Would this work for whole db rather than individual table? How about Primary keys and clustered index?
March 10, 2020 at 12:26 am
Thanks! Would this work for whole db rather than individual table? How about Primary keys and clustered index?
You've got to be really careful about disabling any PK or UNIQUE indexes. From the following BOL article...
When disabling a unique index, the PRIMARY KEY or UNIQUE constraint and all FOREIGN KEY constraints that reference the indexed columns from other tables are also disabled. When disabling a clustered index, all incoming and outgoing FOREIGN KEY constraints on the underlying table are also disabled. The constraint names are listed in a warning message when the index is disabled. After rebuilding the index, all constraints must be manually enabled by using the ALTER TABLE CHECK CONSTRAINT statement.
There are a ton of "Before you begin" warnings on the same page.
--Jeff Moden
Change is inevitable... Change for the better is not.
March 10, 2020 at 11:15 am
I'm with Jeff. Pick and choose which of these indexes you drop & recreate. There are many, many tests out there that show inserting into a clustered table can be (not guaranteed, your mileage may vary, testing needed, trust but verify, all the caveats and warnings) much faster than inserting into a heap.
As far as the rest goes, I strongly advocate for everyone to use source control to manage the code of your databases. Yes, databases are code. You can then use the source code of the indexes as a means of easily automating enabling/disabling or dropping & recreating, as needed.
"The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
- Theodore Roosevelt
Author of:
SQL Server Execution Plans
SQL Server Query Performance Tuning
March 10, 2020 at 11:54 am
I've done many of those tests myself... if you can get Minimal Logging to come into play, the inserting into a Clustered Index is MUCH faster than inserting into a heap and then building the Clustered Index. If you have non-clustered indexes present, then pretty much not despite what the documentation says. I wish the people that did the documentation would have posted the code they used to test with... that's if they actually tested it and aren't just going by some spec that someone wrote.
--Jeff Moden
Change is inevitable... Change for the better is not.
March 13, 2020 at 10:00 pm
Thanks! I ran some tests first with clustered index in-place and second with clustered index dropped, load the data and add the clustered index back . Noticed second one is faster. But still testing with more tables.
March 13, 2020 at 11:16 pm
Thanks! I ran some tests first with clustered index in-place and second with clustered index dropped, load the data and add the clustered index back . Noticed second one is faster. But still testing with more tables.
I can't see what you did. Which Recovery Model where you in, how many rows did you have in the table, and did you follow the rules for "Minimal Logging"?
--Jeff Moden
Change is inevitable... Change for the better is not.
March 13, 2020 at 11:31 pm
Simple recovery model. Approx 15 million rows. Unless bulk-logged is faster than simple?
March 14, 2020 at 12:00 am
Simple recovery model. Approx 15 million rows. Unless bulk-logged is faster than simple?
Simple and Bulk Logged are the same for this type of thing. You didn't answer the rest of the questions, though. Did you follow the rules for "Minimal Logging"?
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 10 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic. Login to reply