Index basics
Think about a regular book: at the end of the book, there's an index that helps to quickly locate
Think about a regular book: at the end of the book, there’s an index that helps to quickly locate
information within the book. The index is a sorted list of keywords and next to each keyword is
a set of page numbers pointing to the pages where each keyword can be found.
A rowstore index is similar: it’s an ordered list of values and for each value there are pointers to
the data
pages
where these values are located. The index itself is also stored on pages, referred
to as
index pages. In a regular book, if the index spans multiple pages and you have to find
pointers to all the pages that contain the word
for example, you would have to leaf
through from the start of the index until you locate the index page that contains the keyword. From there, you follow the pointers to all the book pages. This could be optimized further
if at the very beginning of the index, you create a single page that contains an alphabetical list
of where each letter can be found. For example: “A through D - page 121”, “E through G - page
122” and so on. This extra page would eliminate the step of leafing through the index to find
the starting place. Such a page doesn’t exist in regular books, but it does exist in a rowstore
index. This single page is referred to as the root page of the index. The root page is the starting
page of the tree structure used by an index. Following the tree analogy, the end pages that
contain pointers to the actual data are referred to as “leaf pages” of the tree.
An index is an on-disk or in-memory structure associated with a table or view that speeds
retrieval of rows from the table or view. A rowstore index contains keys built from the values in
one or more columns in the table or view. For rowstore indexes, these keys are stored in a tree
structure (B+ tree) that enables the Database Engine to find the rows associated with the key
values quickly and efficiently.
A rowstore index stores data logically organized as a table with rows and columns, and
physically stored in a row-wise data format called
rowstore. There’s an alternative way to store
data column-wise, called
columnstore.
The design of the right indexes for a database and its workload is a complex balancing act
between query speed, index update cost, and storage cost. Narrow disk-based rowstore
indexes, or indexes with few columns in the index key, require less storage space and a smaller
update overhead. Wide indexes, on the other hand, might improve more queries. You might
have to experiment with several different designs before finding the most efficient set of
indexes. As the application evolves, indexes might need to change to maintain optimal
performance. Indexes can be added, modified, and removed without affecting the database
schema or application design. Therefore, you shouldn’t hesitate to experiment with different
indexes.
The query optimizer in the Database Engine usually chooses the most effective indexes to
execute a query. To see which indexes the query optimizer uses for a specific query, in SQL
1
Query
Display Estimated Execution Plan
Include Actual Execution Plan
Understand the characteristics of the database and the application
Understand the characteristics of the most frequently used queries
Understand the data distribution in the columns used in the query predicates
SQL
SQL