L45 SQL-Developer-Lecture-24
L45 SQL-Developer-Lecture-24
An index, like the index of a book, enables the database retrieve and
present data to the end user with ease
When a SQL Server has NO index to use for searching, the result is
similar to the reader who looks at every page in a book to find a
word: the SQL engine needs to visit every row in a table. In
database terminology we call this behavior a TABLE SCAN, or just
SCAN.
With No Indexes Defined …
Consider the following query on the Products table (with NO index of the Northwind database.
This query retrieves products in a specific price range ( 12.5 – 14).
In the diagram below, the database search touches a total of 77 records to find just three matches.
Now imagine if we CREATED an index, just like a book index, on the data
in the UnitPrice column.
The index will allow the database to quickly narrow in on the three
rows to satisfy the query, and avoid scanning every row in the table.
Creating Indexes
To verify that the index is created, use the following stored procedure to see a list
of all indexes on the Products table:
EXEC sp_helpindex Products
How It Works
The database takes the columns specified in a CREATE INDEX command and sorts
Much like the index in the back of a book helps us to find keywords quickly,
so the database is able to quickly narrow the number of records it must
examine to a minimum by using the sorted list of UnitPrice values stored in
the index.
We have avoided a table scan to fetch the query results
Index Advantages
The query optimizer's job is to find the fastest and least resource
intensive means of executing incoming queries.
The most obvious use for an index is in finding a record or set of records matching a
WHERE clause.
By way of example, the following queries can all benefit from an index on UnitPrice:
Indexes work just as well when searching for a record in DELETE and UPDATE
commands as they do for SELECT statements.
Sorting Records
When we ask for a sorted dataset, the database will try to find an index and avoid sorting the
results during execution of the query.
For example, the following query returns all products sorted by price:
SELECT * FROM Products ORDER BY UnitPrice ASC
With no index, the database will scan the Products table and sort the rows to process the
query. However, the index we created on UnitPrice (IDX_UnitPrice) earlier provides the
database with a presorted list of prices.
The database can simply scan the index from the first entry to the last entry and retrieve the
rows in sorted order.
The same index works equally well with the following query, simply by scanning the index in
reverse.
The following query counts the number of products at each price by grouping
together records with the same UnitPrice value.
To see the space required for a table, use the sp_spaceused system stored procedure
in a query window.
EXEC sp_spaceused Orders
Given a table name (Orders), the procedure will return the amount of space used by
the data and all indexes associated with the table, like so:
Name rows reserved data index_size unused
------- -------- ----------- ------ ---------- -------
Orders 830 504 KB 160 KB 320 KB 24 KB
Indexes and Data Modification
Any time a query modifies the data in a table (INSERT, UPDATE, or DELETE), the database needs
In decision support systems and data warehouses, where information is stored for reporting
purposes, data remains relatively static and report generating queries outnumber data
modification queries. In these types of environments, heavy indexing is commonplace in
order to optimize the reports generated.
In contrast, a database used for transaction processing will see many records added and
updated. These types of databases will use fewer indexes to allow for higher throughput on
inserts and updates.
Clustered Indexes
A common analogy for a clustered index is a phone book.
Since we can only have one clustered index per table, and the testTraining table
already has a clustered index (PK_Products) on the primary key (ProdId), the above
command should generate the following error:
Cannot create more than one clustered index on table ‘testTraining'. Drop the existing
clustered index 'PK_Products' before creating another.
Sometimes it is better to use a unique nonclustered index on the primary key column,
For example, if the majority of searches are for the price of a product instead of the
primary key of a product, the clustered index could be more effective if used on the
price field.
Secondly, you can use a composite index to help match the search criteria of
specific queries. We will go onto more detail and give examples of these two
areas in the following sections.
Covering Queries with an Index
Consider the index we created on the Products table for UnitPrice.
We call these types of queries covered queries, because all of the columns requested in the output are
contained in the index itself.
A clustered index, if selected for use by the query optimizer, always covers a query, since it contains
all of the data in a table.
For the following query, there are no covering indexes on the Products table.
Database will use the index on UnitPrice to avoid sorting records, it will need to follow the
reference in each index entry to find the associated row and retrieve the product name. By
creating a composite index on two columns (ProductName and UnitPrice), we can cover
this query with the new index.
Additional Index Guidelines
Keep Index Keys Short