You are on page 1of 30

Index creation

In SQL Server 2008, you can perform index operations offline or online. The method of index creation is specified using the WITH ONLINE ON | OFF option. By default, indexes are created offline. When building or rebuilding a clustered index offline, the table is exclusively locked and does not allow any type of session to access the table until the index is created or modified. Offline operation of a nonclustered index results in a shared table lock being set, which permits querying of the table using SELECT statements but prevents data modification. Online operations are performed on indexes without locking the table. SQL Server 2008 provides row versioning functionality that allows index operations to take place without interfering with other table operations. The table remains available to users and other sessions. This is often a requirement in busy database environments. However, this functionality is only available in SQL Server 2008 Enterprise Edition. Online index operation can also result in a noticeable performance loss. There is a possibility of data error during online operations. SQL Server adds rows to the new index as they are added to the tables. During an online operation on an index that enforces unique values, a user could enter a value into the new index that later violates uniqueness. Though not common, this happens as a result of timing. The value is entered into the table, but because of how rows are processed, isn't applied to the new index as it is created. If that happens, the online operation terminates with an error. Index operations affect availability and, while they are running, performance. These operations occur when you execute index commands or table commands that create, modify, or delete primary key and unique constraints. There are three types of index operations: creating Creating is the process of initially building the index. rebuilding Rebuilding is the process of recreating the index to restructure based on changes to index keys and options.

dropping Dropping is the process of removing the index. Your two main options when it comes to creating indexes are PRIMARY KEY or UNIQUE constraint the CREATE INDEX statement When you use the CREATE TABLE or ALTER TABLE statements and define a PRIMARY KEY or UNIQUE constraint on a column, a unique index is automatically created to ensure that the PRIMARY KEY or UNIQUE constraint remain distinct. For primary keys, SQL Server creates a unique clustered index by default. An exception is if the table already has a clustered index or you explicitly create it as a unique nonclustered index. To enforce UNIQUE constraints, SQL Server uses a unique nonclustered index by default. You can also explicitly create a unique clustered index, as long as the table doesn't yet have a clustered index defined. You can also create indexes independently of any constraints. To do this, you use the CREATE INDEX statement or SQL Server Management Studio's New Index dialog box. The CREATE INDEX statement has many syntax options, but for each index created you must specify a name, table, and column(s) to which the index applies.

Supplement
Selecting the link title opens the resource in a new browser window.

Job Aid View the job aid Creating Indexes Using a Command to find out about the parameters you can use with the CREATE INDEX statement. This is the syntax for the CREATE INDEX statement.

Syntax
CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX index_name ON <object> (column [ASC | DESC][,...n ] ) [INCLUDE (column_name [,...n ])] [WHERE <filter_predicate>]

[WITH (<index_option> [,...n ])] [ON {partition_scheme_name (column_name) | filegroup_name | "default"}] UNIQUE is an optional keyword you use to create the index as unique. If not specified, SQL Server defaults to a nonunique index. You specify the index as CLUSTERED or NONCLUSTERED. If not specified, SQL Server defaults to a nonclustered index. The index_name is a unique identifier for the index name. The index database and schema are the same as the table or view source. The source specified as the object is the index source from which the key columns are taken. If not specified, SQL Server defaults to the default schema. The column argument is the column list identifying the key columns. The first column is most significant for sort purposes. It sets the sort order to ascending ( ASC) or descending (DESC). If not specified, SQL Server defaults to ascending based on the column collation. The INCLUDE argument specifies the column list for nonkey (included) columns. You use the optional WHERE clause to create a filtered index. The WITH argument sets additional options to further define the index. The ON argument sets an optional destination as a specified filegroup or specifies the partition_schema when creating a partitioned index. For example, to create a simple index called ix_ZIP on the PostalCode column of the Contact table of the Sales database, which you regularly query, you can use this code.

Code
USE Sales CREATE INDEX ix_ZIP ON Sales.Contact(PostalCode) GO If you take it a step further and want to group rows by city and state as well, you need a composite index. In this case, a slight adjustment adds two additional columns to the index.

Code
USE Sales GO CREATE INDEX ix_Addr ON Sales.Contact(PostalCode, City, State) GO

Because no optional keywords were specified to define the indexes, they would default to nonunique, nonclustered in type.

Supplement
Selecting the link title opens the resource in a new browser window.

Job Aid View the job aid Creating Indexes Using Management Studio to learn about the guidelines about how to create indexes. Indexes can also be extended to include nonkey columns in addition to the key columns defined. These nonkey columns are referred to as included columns. This type of index is useful when the included columns are being queried.

Question
What is the correct code to create a simple nonclustered index called ix_Sales_Contact on the PostalCode column of the Sales.Contact table? Options:
1. 2. 3. 4. CREATE INDEX ix_Sales_Contact ON Sales.Contact(PostalCode) CREATE INDEX ON Sales.Contact(PostalCode) CREATE INDEX ix_Sales_Contact ON Sales.Contact(Name) DROP INDEX ix_Sales_Contact ON Sales.Contact(PostalCode)

Answer
Option 1: Correct. The first line of code, CREATE INDEX ix_Sales_Contact, specifies that a new index called ix_Sales_Contact will be created. When neither CLUSTERED or NON-CLUSTERED is specified, a nonclustered index will be created by default. The second line of code specifies that index is created on the PostalCode column of the Sales.Contact table. Option 2: Incorrect. The first line of code, CREATE INDEX, does not specify the name of the index.

Option 3: Incorrect. The second line of code, ON Sales.Contact(Name), specifies that the index will be created on the Name column, whereas it should actually specify the PostalCode column. Option 4: Incorrect. In the first line of code, the CREATE INDEX statement should be used, not the DROP INDEX statement. Correct answer(s): 1. CREATE INDEX ix_Sales_Contact ON Sales.Contact(PostalCode) Another common use of the INCLUDE clause is to overcome the 900-byte maximum key column restriction. Consider a table that has three columns you commonly query and which you would like to create an index on. One of these columns, however, is a Description column of data type nvarchar (max), which is much too large to index because it would surpass the allowable key column size. This example creates a nonclustered index ix_Prod with the ProductID and Rating column as the key columns and the Description column as an included nonkey column.

Code
USE Sales GO CREATE NONCLUSTERED INDEX ix_Prod ON Products.Productinfo(ProductID, Name) INCLUDE (Description) GO If you need to create a filtered index, you use the WHERE clause to define a filter predicate. As the name implies, the filtered index is used when only a certain subset of rows within a column should be indexed. For example, to create a filtered, nonclustered index on the SalesOrders table, you select only the rows where it reads that the ShipDate is NULL and execute this statement.

Code
USE Sales GO CREATE NONCLUSTERED INDEX ix_Orders ON SalesOrders.Orders(CustomerID, OrderDate)

WHERE ShipDate IS NULL GO

Question
When creating a filtered index, what argument is specified with the CREATE INDEX statement to define a filter predicate? Options:
1. 2. 3. 4. WHERE <filter_predicate> INCLUDE <filter_predicate> WITH <filter_predicate> ON <filter_predicate>

Answer
Option 1: Correct. If you need to create a filtered index, you use the WHERE clause to define a filter predicate. As the name implies, the filtered index is used when only a certain subset of rows within a column should be indexed. An example of this is WHERE ShipDate IS NULL. Option 2: Incorrect. The INCLUDE argument is used when a nonkey column should be added to the index. Option 3: Incorrect. The WITH clause is used to include additional options to further define the index. Option 4: Incorrect. The ON clause is used to set optional destination parameters. This may be a specific filegroup, or it can specify the partition_schema when creating a partitioned index. Correct answer(s): 1. WHERE <filter_predicate>

2. Index rebuilding and dropping


SQL Server 2008 provides XML indexes specifically to optimize query performance for XML data type columns. XML indexes can be beneficial if you have applications that perform a considerable amount of queries on XML columns. You should also consider them if your XML instances are large and you want to avoid parsing all data at runtime.

The XML column type stores XML instances in the form of binary large objects (BLOBs), which can often be up to 2 GB in size. When queried, the binary large objects are shredded, which takes time. The XML index makes query processing much more efficient. There are two types of XML indexes: primary The primary XML index is the first to be declared and indexes all the XML tags, values, and paths of the XML instance of the column. In order to be able to create a primary XML index on a table, there must be an existing PRIMARY KEY and corresponding clustered index defined on the table. This primary key is needed to draw a parallel between the rows of the table XML column and the rows of the primary XML index. There can only be one primary XML index per XML column. secondary Secondary XML indexes can be defined on an existing primary XML index to further optimize query performance. The type of secondary XML indexes that can be defined include PATH, VALUE, and PROPERTY. A PATH secondary index is typically helpful if queries involve path expressions on xml data type columns. A VALUE secondary index is generally created to optimize queries that specify a value or incomplete path. A PROPERTY secondary index is suited to queries that return values from individual XML instances. There can be multiple secondary XML indexes per xml column. Before implementing XML indexes on xml data type columns in your tables, you should consider that a table can include a maximum of 249 XML indexes the clustered index key on the table can include a maximum of 15 columns all XML indexes are created on a single xml data type column XML indexes cannot be created on a view, table-valued variable, computed xml column, or xml type variable The T-SQL statement used to create an XML index is slightly modified from the standard CREATE INDEX statement.

Syntax
CREATE [PRIMARY] XML INDEX index_name ON <object>(xml_column_name)

[USING XML INDEX xml_index_name [FOR {VALUE | PATH | PROPERTY}]] [WITH (<xml_index_options> [ ,...n ])] To create an XML index on the specified object, you use [PRIMARY] XML. If a fully qualified name is provided, tables in another database may be specified. The XML index can be created before the table data exists. The index_name is a unique identifier for the index name. Index names should be unique to the table and primary XML indexes should not start with the characters #, ##, @, or @@. The <object> argument refers to the index source from which the XML columns are taken. If not specified, SQL Server defaults to the default schema. The (xml_column_name) argument refers to the XML column the index is based on. You use xml_index_name to specify the associated primary XML index when defining a secondary XML index. You use FOR { VALUE | PATH | PROPERTY } to specify the type of secondary XML indexes. The WITH(<xml_index_options> argument refers to additional options used to further define the XML index. For example, this statement creates a primary XML index on the ProductReview xml column of the Products.productinfo table.

Code
USE Sales GO CREATE PRIMARY XML INDEX XML_IX_prodinfo ON Products.productinfo (ProductReview) GO CREATE XML INDEX XML_IX_prodinfo_value ON Products.productinfo (ProductReview) USING XML INDEX XML_IX_prodinfo FOR VALUE GO This statement creates a PROPERTY secondary XML index associated with the primary XML index. New in SQL Server 2008 is the support for spatial data, such as geometric data and geographic objects.

Supplement

Selecting the link title opens the resource in a new browser window.

Job Aid Access the job aid Creating Spatial Indexes to view a list of command syntax and parameters for the CREATE SPATIAL INDEX command. The geometry data type supports planar spatial data, such as points, lines, and polygons. The geography data type deals with two-dimensional spatial data, such as an area of land. You can create spatial indexes on spatial data columns of a table or view. This is the basic syntax for creating a spatial index.

Syntax
CREATE SPATIAL INDEX index_name ON <object> (spatial_column_name) {[USING <geometry_grid_tessellation>] WITH (<bounding_box> [[,] <tesselation_parameters> [ ,...n ]] [[,] <spatial_index_option> [ ,...n ]]) | [USING <geography_grid_tessellation> ] [WITH ([ <tesselation_parameters> [ ,...n ]] [[,] <spatial_index_option> [ ,...n ]])]} [ON { filegroup_name | "default" } ] The index_name is a unique identifier for the index name. Index names need to be unique within the table but not database. ON <object> (spatial_column_name) refers to the object on which the index is created and the name of the spatial column it is based on. You can only specify one spatial index per index definition but you can create multiple spatial indexes on a spatial column. USING <geometry_grid_tessellation> and USING <geography_grid_tessellation> are used to specify the tessellation scheme. For <geometry_grid_tessellation> you use the GEOMETRY_GRID keyword, and for <geography_grid_tesselation> you use the GEOGRAPHY_GRID keyword. You use the <bounding_box> to define the four coordinates of the bounding box. It only applies to the USING GEOMETRY_GRID clause. The <tesselation_parameters> argument refers to the additional options used to further define the tessellation. The <spatial_index_option> argument refers to the additional options used to further define the spatial index.

When you drop a clustered index, SQL Server deletes the nonleaf nodes and reorganizes the table as a heap. When you drop a nonclustered index, SQL Server deletes all leaf and nonleaf nodes. This is the syntax for the DROP INDEX statement which you use to delete indexes.

Syntax
DROP INDEX index_name ON table_or_view [WITH (ONLINE = ON | OFF, MAXDROP = max_deg_of_parallelism, MOVE TO filegroup | partition_schema | DEFAULT)] The syntax for specifying the index is the same as for the CREATE INDEX and ALTER INDEX commands identifier ON and the base table or view. You use the ONLINE option when dropping a clustered or nonclustered index. You use the MAXDROP option when dropping a clustered or nonclustered index. You use MOVE TO with clustered indexes only. When using the MOVE TO option, you specify the location for the table after you drop a clustered index. This example drops the ix_Orders clustered index of the SalesOrders.Orders table, while keeping the table online. To move the data rows of the index to a filegroup called "Filegroup3", this statement must be executed.

Code
USE Sales GO DROP INDEX ix_Orders ON SaleOrders.Orders WITH (ONLINE = ON, MOVE TO Filegroup3) GO Because the table is reorganized as a heap when you drop a nonclustered index, SQL Server rebuilds all nonclustered indexes at the same time. If you drop a table, SQL Server drops all indexes on that table automatically.

Summary

SQL Server 2008 enables you to perform index operations offline or online. By default, indexes are created offline. You have two main options when it comes to creating indexes: PRIMARY KEY or the UNIQUE constraint. You can also create indexes independently of any constraints. XML indexes are provided to optimize query performance for xml data type columns. They can be useful if you have applications that perform a considerable amount of queries on XML columns, or if your XML instances are large and you want to avoid parsing all data at runtime.

Modifying indexes
There will be times when you need to modify the indexes and index properties that you have created. To do this, you use the CREATE INDEX or ALTER INDEX commands to modify indexes. However, if you need to change the index key columns or included columns, you can't use the ALTER INDEX statement. You'll need to use the CREATE INDEX statement with the DROP_EXISTING clause instead. The CREATE INDEX command modifies an index by dropping and recreating it with the defined parameters.

Code
USE Sales GO CREATE INDEX ix_Orders ON Saleorders.Orders(SalesOrderID, CustomerID, OrderDate) WITH (PAD_INDEX = ON, FILLFACTOR = 50, DROP_EXISTING = ON) GO You must specify the DROP_EXISTING option when using CREATE INDEX to recreate an existing index. To recreate an index called ix_Orders, you could run this code.

Code
USE Sales GO CREATE INDEX ix_Orders ON Saleorders.Orders(SalesOrderID, CustomerID, OrderDate)

WITH (PAD_INDEX = ON, FILLFACTOR = 50, DROP_EXISTING = ON) GO You have the option of making changes to the index specifications, such as key columns and index options used, when you use DROP_EXISTING. For example, to change the key columns, index padding, and fill factor of the previously created index ix_Orders, you execute this code.

Code
USE Sales GO CREATE INDEX ix_Orders ON Saleorders.Orders(SalesOrderID, CustomerID, OrderDate) WITH (PAD_INDEX = ON, FILLFACTOR = 50, DROP_EXISTING = ON) GO CREATE INDEX ix_Orders ON SaleOrders.Orders(SalesOrderID, CustomerID) WITH (PAD_INDEX = OFF, FILLFACTOR = 60, DROP_EXISTING = ON) GO Alternatively, you can use the ALTER INDEX statement to modify your indexes.

Code
ALTER INDEX {index_name | ALL} ON object {REBUILD [WITH options] | DISABLE | REORGANIZE [WITH options] | SET [options]

Supplement
Selecting the link title opens the resource in a new browser window.

Job Aid Access the job aid Altering Indexes to view the detailed syntax of the ALTER INDEX statement. Using the ALTER INDEX statement, you can

Code
ALTER INDEX {index_name | ALL} ON object {REBUILD [WITH options] | DISABLE | REORGANIZE [WITH options] | SET [options] disable an index rebuild an index reorganize an index alter options of the index The ALTER INDEX statement cannot be used to

Code
ALTER INDEX {index_name | ALL} ON object {REBUILD [WITH options] | DISABLE | REORGANIZE [WITH options] | SET [options] repartition the index move the index to another location modify index columns This is the syntax of the ALTER INDEX statement.

Syntax
ALTER INDEX {index_name | ALL} ON object {REBUILD [WITH options] | DISABLE | REORGANIZE [WITH options] | SET [options]

The index_name argument refers to the name of the index, when modifying one index. ALL is the keyword used when modifying all indexes on the table or view. ON object specifies the index database, schema, and table or view. REBUILD specifies to rebuild the index with the original columns, type, uniqueness, and sort order. The index is disabled during this rebuild. To disable the index so that it is not available to the database engine you use DISABLE. To enable a disabled index, you run ALTER INDEX with REBUILD or CREATE INDEX with DROP_EXISTING. To reorganize the index only at the leaf level, you use REORGANIZE. This argument is used to defragment a fragmented index. This operation always runs as online. SET specifies additional index options.

Question
Which statements regarding the ALTER INDEX command are true? Options:
1. 2. 3. 4. Indexes can be rebuilt using the ALTER INDEX statement Indexes can be disabled using the ALTER INDEX statement Indexes can be repartitioned using the ALTER INDEX statement Indexes can be moved using the ALTER INDEX statement

Answer
Option 1: Correct. You use the REBUILD clause of the ALTER INDEX statement to defragment or rebuild an index. Option 2: Correct. You can use the DISABLE clause with the ALTER INDEX statement to disable an index so that it is not available to the database engine. Option 3: Incorrect. You cannot repartition an index using the ALTER INDEX statement. Instead, you need to use the CREATE INDEX statement with the DROP_EXISTING clause. Option 4: Incorrect. You cannot move an index to a new location using the ALTER INDEX statement. Instead, you need to use the CREATE INDEX statement with the DROP_EXISTING clause. Correct answer(s):

1. Indexes can be rebuilt using the ALTER INDEX statement 2. Indexes can be disabled using the ALTER INDEX statement Of course, you can also use SQL Server Management Studio to perform index modification tasks. You use either the Indexes/Keys dialog box or the indexes folder properties to modify an existing index. To modify an index by using the SQL Server Management Studio Indexes/Keys dialog box, you right-click the table and choose Design.

Graphic
The dbo. Employees table has been right-clicked. You right-click a column and choose Indexes/Keys.

Graphic
In this case, the EmployeeID column has been right-clicked. You select an existing index to modify.

Graphic
The Indexes/Keys dialog box contains a Selected Primary/Unique Key or Index panel and an Editing properties for existing primary/unique key or index window. You set the index parameters as required.

Graphic
This includes General, Identity, and Table Designer parameters. When using the Indexes/Keys dialog box, you can modify the following properties: Columns Is Unique Type (Name) Description

Data Space Specification Fill Specification Ignore Duplicate Keys Re-compute statistics When using the Indexes/Keys dialog box, you can't

remove key columns modify included columns change properties other than those listed You can modify the Columns property to add but not remove key columns. To save the table changes, you click Save.

Note
A dialog box reports any errors that prevent the database engine from modifying the index. You can right-click any individual index to rebuild the index reorganize the index disable the index delete the index rename the index view the index's properties The Indexes folder enables you to rebuild all indexes reorganize all indexes

disable all indexes To modify any index, you expand the Indexes folder. You right-click the index and choose Properties. You modify the necessary index properties and then click OK.

Graphic
To facilitate and monitor progress, the Index Properties IX_Employees dialog box contains Select a page, Connection, and Progress sections on the left-hand side. On the right-hand side, Table name, Index name, and Index type text boxes and a Unique checkbox enable properties configuration. The Index key columns pane, comprising the Name, Sort Order, Data Type, and Size columns allow for definition and selection.

2. Rebuilding indexes
When insert, update, or delete operations are performed on the data within a database, the SQL Server Database Engine maintains indexes automatically. Over time, such changes can lead to the data in an index becoming disordered. This state is known as fragmentation. Fragmentation is caused when the logical order of a page in an index, which is based on the key value, no longer corresponds to the actual ordering within the data file. Fragmentation is a significant problem because seriously fragmented indexes can lead to poor query performance and slow application response. If you encounter fragmentation issues, two options are available to you to address the problem. You can either reorganize an index a process known as defragmentation or choose to completely rebuild it.

Note
In the case of partitioned indexes constructed on a partition scheme, you can opt to employ either of these processes on a whole index or on an individual index partition. Before you can determine which method to employ to address fragmentation, you need to analyze the index in question to establish the degree of fragmentation.

You can run this dynamic management function to identify fragmentation issues in an individual index, every index on a table or indexed view, every index in a database, or every index in every database. You can also use this function to generate fragmentation data for separate partitions in a partitioned index.

Code
sys.dm_db_index_physical_stats {database_id | NULL | 0 | DEFAULT} , {object_id | NULL | 0 | DEFAULT} , {index_id | NULL | 0 | -1 | DEFAULT} , {partition_number | NULL | 0 | DEFAULT} , {mode | NULL | DEFAULT} Three important columns are included in the result set returned by the sys.dm_db_index_physical_stats system function. avg_fragmentation_in_percent The avg_fragmentation_in_percent column displays the logical fragmentation, which is the number of disordered pages in the index, expressed as a percentage. It also displays the percentage of extent fragmentation for heap tables. fragment_count The fragment_count column indicates how many fragments or physically consecutive leaf pages are present in the index. avg_fragment_size_in_pages The avg_fragment_size_in_pages column displays the mean number of pages in a single fragment in an index. For example, say you are a database administrator at the firm Brocadero and you want to analyze your Sales database to check for fragmentation. You can use this code to return information concerning all indexes and tables for all databases.

Graphic
The code that does this is SELECT * FROM sys.dm_db_index_physical_stats null,null,null,null,null)

Code

USE sales GO SELECT * FROM sys.dm_db_index_physical_stats null,null,null,null,null) GO Now you want to view data about a particular group of indexes. You can use this code to return information about all indexes that are clustered for the database that has the id number of 1.

Code
USE sales GO SELECT * FROM sys.dm_db_index_physical_stats (1, null, null, null, null) WHERE index_type_desc = 'CLUSTERED INDEX' GO If you do not know the database id and object id the index is on, you can use the DB_ID and OBJECT_ID functions within the parameters for the function to allow the system to determine them.

Graphic
The code for this is SELECT * FROM sys.dm_db_index_physical_stats (DB_ID('Sales'), OBJECT_ID(Sales.HR.EMP'), null, null, 'DETAILED')

Code
USE Sales GO SELECT * FROM sys.dm_db_index_physical_stats (DB_ID('Sales'), OBJECT_ID('Sales.HR.EMP'), null, null, 'DETAILED') GO Once you have used the sys.dm_db_index_physical_stats system function to determine the degree of fragmentation, you are ready to decide which method to use to address fragmentation. As a rule of thumb, if the degree of fragmentation is above 5% but below or equal to 30%, you should opt to defragment or reorganize the index.

However, if the level of fragmentation is more than 30%, you should consider rebuilding the index.

Note
Levels of fragmentation below 5% do not merit the use of either of these methods. This is because the slight benefit in terms of index performance afforded by rectifying such a small amount of fragmentation cannot justify the cost of defragmenting or rebuilding the index. You use the REORGANIZE and REBUILD clauses of the ALTER INDEX statement to defragment or rebuild an index respectively.

Syntax
ALTER INDEX {index_name | ALL} ON object {REBUILD [WITH options] | DISABLE | REORGANIZE [WITH options] | SET [options] You should use the ALTER INDEX REBUILD statement when the index is heavily fragmented. Although you can rebuild indexes both offline or online, you should conduct this process online if you want to achieve availability similar to that offered by reorganization. When you rebuild an index, you are dropping the index and creating a new one. As a result, fragmentation is eliminated. Disk space is restored because the pages have been reordered using the specified or current fill factor setting, and the index rows have been reordered in adjacent pages, with new pages being allocated as necessary. This can enhance disk performance by cutting down the number of page reads needed to find the requested information. You should use the ALTER INDEX REORGANIZE statement when the index is not heavily fragmented. Reorganizing an index uses only a small portion of the system resources. Reorganization is carried out online. Because reorganizing an index does not put in place long-term blocking locks, it will not prevent running queries or updates. As a database administrator for Red Rock Mountain Tours, you wish to address a fragmentation issue with the index PK_EMP_empID on the HR.EMP table. You have used the sys.dm_db_index_physical_stats system function to determine the degree of fragmentation, and found it to be at 15%.

So you opt to reorganize the index. You use this code to reorganize the index.

Code
ALTER INDEX PK_EMP_empID ON HR.EMP REORGANIZE

Next you want to address a fragmentation issue with another nonclustered index. Again, you have used the sys.dm_db_index_physical_stats system function to gauge the degree of fragmentation. This time the fragmentation level is at 75%. This is a heavy degree of fragmentation, so you decide to rebuild the index. Before you rebuild the index, you need to disable it to free space for the rebuild. You can use this code to do this.

Code
ALTER INDEX IX_DeptID ON HR.Dept DISABLE The advantage of disabling and rebuilding a nonclustered index in separate stages is that the disk space afforded by disabling the index can be reused by the next rebuild or by any other operation.

Code
ALTER INDEX IX_DeptID ON HR.Dept DISABLE You begin rebuilding the index by using the ALTER INDEX statement, specifying the index name and the database that it is on.

Code
ALTER INDEX IX_DeptID ON HR.Dept

REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON, STATISTICS_NORECOMPUTE = ON); ALTER INDEX PK_empID ON HR.EMP REBUILD Partition = 5 You use the REBUILD keyword to specify that the index should be rebuilt and add this code to specify the fill factor and to ensure statistics will not be automatically regenerated for the rebuilt index.

Code
ALTER INDEX IX_DeptID ON HR.Dept REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON, STATISTICS_NORECOMPUTE = ON); ALTER INDEX PK_empID ON HR.EMP REBUILD Partition = 5 Finally, you want to rebuild a single partition in another, partitioned, index. You use this variation containing a PARTITION clause to specify that only partition 5 will be rebuilt.

Code
ALTER INDEX IX_DeptID ON HR.Dept REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON, STATISTICS_NORECOMPUTE = ON); ALTER INDEX PK_empID ON HR.EMP REBUILD Partition = 5

Question
You have determined that the degree of fragmentation on the index PK_EMP_prodID is 20%. You want to address the fragmentation issue. To do this, what should the next line of code be?

Code ALTER INDEX PK_prodID ON Products.ProductID INSERT THE MISSING CODE Options:
1. REORGANIZE 2. 3. 4. REBUILD DISABLE ALL

Answer
Option 1: Correct. You should use the REORGANIZE option when the index fragmentation is less than 30%. Reorganizing an index uses only a small portion of system resources. Reorganization is carried out online. Option 2: Incorrect. You should use the REBUILD option when the index fragmentation is more than 30%. Although you can rebuild indexes both offline or online, you should conduct this process online if you want to achieve availability similar to that offered by reorganization. Option 3: Incorrect. The DISABLE option disables an index so that it is not available to the database engine. Option 4: Incorrect. The ALL keyword is used with ALTER INDEX when modifying all indexes on the table or view. Correct answer(s):
1. REORGANIZE

3. Managing indexes
You are also able to rename your existing indexes. As with the original name, the new index name must be unique to the table or view it is created on but does not need to be unique within the database. Creating index names that match a disabled index is also not permitted. When it comes to naming and renaming indexes, you should keep in mind that SQL Server automatically creates an index for every PRIMARY KEY and UNIQUE constraint that exists on a table. These indexes will have the same name as the associated table.

For example, if a primary key is created on the CustomerID column of the SaleOrders.Customers table, an index called PK_Customers automatically appears under Indexes.

Note
The renaming process does not automatically require the index to be rebuilt. You use the sp_rename stored procedure to rename an index.

Syntax
sp_rename [@objname = ] 'object_name', [@newname = ] 'new_name' [, [@objtype = ] 'object_type'] To specify the partially or fully qualified name of the object, you use this syntax: @objname = 'object_name' Indexes being renamed must be referenced using the table.index or schema.table.index form. You specify the new name to be given to the object using this syntax: @newname = 'new_name' And to specify the type of object being renamed, you use this syntax: @objtype = 'object_type' Values provided can include COLUMN, DATABASE, INDEX, OBJECT, or USERDATATYPE. This example renames the index ix_Orders in the Orders table to ix_OrderID.

Code
USE Sales GO EXEC sp_rename ('SaleOrders.Orders.ix_Orders', 'ix_OrderID', 'INDEX') GO

You will receive a cautionary note that renaming objects can break scripts and stored procedures. It is not recommended to use the sp_rename function to rename stored procedures, triggers, user-defined functions, or views. When using the sp_rename only objects in the current database can be renamed indexes associated with renamed PRIMARY KEY or UNIQUE constraints are automatically renamed primary and secondary XML indexes can be renamed To rename an index using the Object Explorer in SQL Server Management Studio, you simply expand the Indexes folder of the database table, right-click the index, and choose Rename from the pop-up menu. There are also situations where you need to disable an index. Indexes can be disabled using this version of the ALTER INDEX statement.

Code
USE Sales GO ALTER INDEX {index_name | ALL} ON <object> DISABLE GO

Syntax
USE Sales GO ALTER INDEX {index_name | ALL} ON <object> DISABLE GO When disabled, the index is not operational and it is not stored as part of data. Instead, its definition is kept intact and is stored in the system catalog. You should be careful when disabling a clustered index, though the whole table becomes inaccessible when a clustered index is disabled.

Code
USE Sales GO ALTER INDEX {index_name | ALL} ON <object> DISABLE GO Enabling the index again involves rebuilding it to recreate the structure. You execute the ALTER INDEX statement with the REBUILD keyword to enable the index.

Code
USE Sales GO ALTER INDEX {index_name | ALL} ON <object> REBUILD GO You can also use the SQL Server Management Studio to easily disable an index. To do this, you first expand the database and table storing the index. You expand the table and right-click the Indexes folder. From the pop-up menu, you can choose to Disable All indexes. To disable a specific index, you expand the Indexes folder, right-click the index, and choose Disable from the pop-up menu.

4. Configuring indexes
When modifying an index using the ALTER INDEX REBUILD statement, you have the option to modify a number of index-specific options. If you need to make changes but do not want to rebuild the index, you can also use the ALTER INDEX statement with the SET clause to change specific options.

Code
USE Sales GO ALTER INDEX ix_ProductID

ON Products.ProductID SET (ALLOW_PAGE_LOCKS = IGNORE_DUP_KEY = OFF) GO Index options that can be changed using the SET clause and without the need to rebuild the index include

Code
USE Sales GO ALTER INDEX ix_ProductID ON Products.ProductID SET (ALLOW_PAGE_LOCKS = IGNORE_DUP_KEY = OFF) GO ALLOW_PAGE_LOCKS The ALLOW_PAGE_LOCKS option is set to ON to specify that page locks are to be used when index data is accessed. ALLOW_ROW_LOCKS The ALLOW_ROW_LOCKS option is set to ON to specify that row locks are to be used when index data is accessed. IGNORE_DUP_KEY The IGNORE_DUP_KEY option can be set to determine what action is taken if there is an attempt to insert duplicate key values into a unique clustered or unclustered index. When it is set to ON, SQL Server presents an error and does not perform the insert action for the specific violating rows. When it is set to OFF, an error is issued and the entire INSERT operation is rolled back. The default is OFF. STATISTICS_NORECOMPUTE The STATISTICS_NORECOMPUTE option is set to indicate if distribution index statistics should be recomputed. When set to ON, out-of-date statistics will not need to be automatically recomputed. Setting it to OFF enables automatic updating of statistics. The default is OFF. For example, you use this statement to modify an index so that page locks are allowed when accessing index data and entire insert operations are rolled back if they attempt to add duplicate row values.

Graphic
The statement is ALTER INDEX ix_ProductID

ON Products.ProductID SET (ALLOW_PAGE_LOCKS = IGNORE_DUP_KEY = OFF)

Code
USE Sales GO ALTER INDEX ix_ProductID ON Products.ProductID SET (ALLOW_PAGE_LOCKS = IGNORE_DUP_KEY = OFF) GO Index creation and modification does not take place instantly. The process actually takes place in three phases:

Code
USE Sales GO ALTER INDEX ix_ProductID ON Products.ProductID SET (ALLOW_PAGE_LOCKS = IGNORE_DUP_KEY = OFF) GO preparation The preparation phase is a very short phase where the system metadata is prepared to create the initial empty index structure. build The building phase is the main phase, where all the source data is scanned, sorted, and then inserted into the new target index structure. final The final phase involves the final clean-up processes, where metadata is updated and source data is dropped or replaced with the new index data. During this time, there is a chance that index key data is being accessed and possibly changed. SQL Server ensures the consistency of data during the index building process and allows you to create or alter indexes either online or offline. If not specified, the default setting is ONLINE OFF.

Code

USE Sales GO ALTER INDEX ix_ProductID ON Products.ProductID SET (ALLOW_PAGE_LOCKS = IGNORE_DUP_KEY = OFF) GO There are two clauses you can use to define SQL Server behavior during index creation:

Code
USE Sales GO ALTER INDEX ix_ProductID ON Products.ProductID SET (ALLOW_PAGE_LOCKS = IGNORE_DUP_KEY = OFF) GO ONLINE ON When the online option is set, changes will continue to be permitted to the underlying table during the index creation process. SQL Server uses row versioning functionality and the tempdb database to ensure index creation and other table operations are not in conflict. This functionality is only available in SQL Server Enterprise, Developer, and Evaluation Editions. OFFLINE OFF When the offline option is set, the underlying table is locked and does not allow any changes to take place until the index creation process has completed. SQL Server behaves slightly differently, depending on the type of index. When a clustered index is created in an offline mode, the table is completely locked for both changes and queries. When the index is nonclustered, the table is still locked for data changes but SELECT statements are permitted. The WITH ONLINE option is available in the CREATE INDEX and ALTER INDEX statements, as well as the DROP INDEX and ALTER TABLE statements. This means that indexes can be created, rebuilt, and dropped while online.

Code
USE Sales GO ALTER INDEX ALL ON SaleOrders.Orders

REBUILD WITH (ONLINE = ON) GO For example, if you'd like to rebuild your indexes on the Orders table while keeping the table data accessible, you'd use this code.

Graphic
The code is ALTER INDEX ALL ON SaleOrders.Orders REBUILD WITH (ONLINE = ON)

Code
USE Sales GO ALTER INDEX ALL ON SaleOrders.Orders REBUILD WITH (ONLINE = ON) GO

Summary
You can use the CREATE INDEX and ALTER INDEX commands to modify indexes. You can also use SQL Server Management Studio to perform index modification tasks. Fragmentation is caused when the logical order of a page in an index no longer corresponds to the actual ordering within the data file. Fragmentation is a significant problem because it can lead to poor query performance and slow application response. You can rename your existing indexes and disable an index. Indexes can be enabled again by rebuilding it to recreate the structure. You can also modify an index using the ALTER INDEX REBUILD statement, which gives you the option to modify a number of index-specific options.

You might also like