index creation
TRANSCRIPT
-
7/28/2019 Index Creation
1/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.
-
7/28/2019 Index Creation
2/30
dropping
Dropping is the process of removing the index.
Your two main options when it comes to creating indexes are
PRIMARY KEY orUNIQUE constraint
the CREATE INDEX statement
When you use the CREATE TABLE orALTER TABLE statements and define a PRIMARY
KEY orUNIQUE constraint on a column, a unique index is automatically created to ensure
that the PRIMARY KEY orUNIQUE 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 Commandto 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 (column [ASC | DESC][,...n ] )
[INCLUDE (column_name [,...n ])]
[WHERE ]
http://dowindow%28%27../html/jamd_mcim_a05_l5_t16_101_frame.html')http://dowindow%28%27../html/jamd_mcim_a05_l5_t16_101_frame.html')http://dowindow%28%27../html/jamd_mcim_a05_l5_t16_101_frame.html') -
7/28/2019 Index Creation
3/30
[WITH ( [,...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 orNONCLUSTERED. 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 optionalWHERE 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
-
7/28/2019 Index Creation
4/30
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. CREATE INDEX ix_Sales_Contact
ON Sales.Contact(PostalCode)
2. CREATE INDEX
ON Sales.Contact(PostalCode)
3. CREATE INDEX ix_Sales_Contact
ON Sales.Contact(Name)
4. DROP INDEX ix_Sales_Contact
ON Sales.Contact(PostalCode)
Answer
Option 1: Correct. The first line of code, CREATE INDEXix_Sales_Contact,
specifies that a new index called ix_Sales_Contact will be created. When neither
CLUSTERED orNON-CLUSTERED is specified, a nonclustered index will be createdby 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.
http://dowindow%28%27../html/jamd_mcim_a05_l5_t16_102_frame.html')http://dowindow%28%27../html/jamd_mcim_a05_l5_t16_102_frame.html') -
7/28/2019 Index Creation
5/30
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 typenvarchar (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)
-
7/28/2019 Index Creation
6/30
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. WHERE
2. INCLUDE
3. WITH
4. ON
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 WHEREShipDateISNULL.
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
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.
-
7/28/2019 Index Creation
7/30
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.
secondarySecondary 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 (xml_column_name)
-
7/28/2019 Index Creation
8/30
[USING XML INDEXxml_index_name
[FOR {VALUE | PATH | PROPERTY}]]
[WITH ( [ ,...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 indexcan 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 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( 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
-
7/28/2019 Index Creation
9/30
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_nameON (spatial_column_name)
{[USING ]
WITH (
[[,] [ ,...n ]]
[[,] [ ,...n ]])
| [USING ]
[WITH ([ [ ,...n ]]
[[,] [ ,...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 (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 and
USING are used to specify the tessellation scheme. For
you use the GEOMETRY_GRID keyword, and for
you use the GEOGRAPHY_GRID keyword.
You use the to define the four coordinates of the bounding box. It only
applies to the USING GEOMETRY_GRID clause.
The argument refers to the additional options used to further
define the tessellation.
The argument refers to the additional options used to further
define the spatial index.
http://dowindow%28%27../html/jamd_mcim_a05_l5_t16_103_frame.html')http://dowindow%28%27../html/jamd_mcim_a05_l5_t16_103_frame.html') -
7/28/2019 Index Creation
10/30
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 theDROP
INDEX
statement which you use to delete indexes.
Syntax
DROP INDEX index_name
ONtable_or_view
[WITH (ONLINE = ON | OFF,
MAXDROP = max_deg_of_parallelism,
MOVE TOfilegroup |partition_schema | DEFAULT)]
The syntax for specifying the index is the same as for the CREATEINDEX andALTER
INDEX commands identifierON 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
-
7/28/2019 Index Creation
11/30
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 youhave created. To do this, you use the CREATE INDEX orALTER 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)
-
7/28/2019 Index Creation
12/30
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
http://dowindow%28%27../html/jamd_mcim_a05_l5_t7_101_frame.html')http://dowindow%28%27../html/jamd_mcim_a05_l5_t7_101_frame.html') -
7/28/2019 Index Creation
13/30
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 ALTERINDEX statement.
Syntax
ALTER INDEX {index_name |ALL}
ONobject
{REBUILD [WITH options] |
DISABLE |
REORGANIZE [WITH options] |
SET [options]
-
7/28/2019 Index Creation
14/30
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 orCREATE 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. Indexes can be rebuilt using the ALTER INDEX statement
2. Indexes can be disabled using the ALTER INDEX statement
3. Indexes can be repartitioned using the ALTER INDEX statement
4. 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):
-
7/28/2019 Index Creation
15/30
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
-
7/28/2019 Index Creation
16/30
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
-
7/28/2019 Index Creation
17/30
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.
-
7/28/2019 Index Creation
18/30
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 thesys.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
-
7/28/2019 Index Creation
19/30
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.
-
7/28/2019 Index Creation
20/30
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 ALTERINDEXREBUILD 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 ALTERINDEXREORGANIZE 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%.
-
7/28/2019 Index Creation
21/30
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
-
7/28/2019 Index Creation
22/30
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?
-
7/28/2019 Index Creation
23/30
Code
ALTER INDEX PK_prodID
ON Products.ProductID
INSERT THE MISSING CODE
Options:
1. REORGANIZE
2. REBUILD
3. DISABLE
4. 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. TheALL
keyword is used withALTER 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 iscreated 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.
-
7/28/2019 Index Creation
24/30
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, orUSERDATATYPE.
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
-
7/28/2019 Index Creation
25/30
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 orUNIQUE 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
DISABLE
GO
Syntax
USE Sales
GO
ALTER INDEX {index_name | ALL}
ON
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.
-
7/28/2019 Index Creation
26/30
Code
USE Sales
GO
ALTER INDEX {index_name | ALL}
ON
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
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
-
7/28/2019 Index Creation
27/30
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 toadd duplicate row values.
Graphic
The statement is
ALTER INDEX ix_ProductID
-
7/28/2019 Index Creation
28/30
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
-
7/28/2019 Index Creation
29/30
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 DROPINDEX 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
-
7/28/2019 Index Creation
30/30
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 SalesGO
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.