What is a Covered Index?

I've just heard the term covered index in some database discussion - what does it mean?


A covering index is an index that contains all of, and possibly more, the columns you need for your query.

For instance, this:

SELECT *
FROM tablename
WHERE criteria

will typically use indexes to speed up the resolution of which rows to retrieve using criteria, but then it will go to the full table to retrieve the rows.

However, if the index contained the columns column1, column2 and column3, then this sql:

SELECT column1, column2
FROM tablename
WHERE criteria

and, provided that particular index could be used to speed up the resolution of which rows to retrieve, the index already contains the values of the columns you're interested in, so it won't have to go to the table to retrieve the rows, but can produce the results directly from the index.

This can also be used if you see that a typical query uses 1-2 columns to resolve which rows, and then typically adds another 1-2 columns, it could be beneficial to append those extra columns (if they're the same all over) to the index, so that the query processor can get everything from the index itself.

Here's an article: Index Covering Boosts SQL Server Query Performance on the subject.


Covering index is just an ordinary index. It's called "covering" if it can satisfy query without necessity to analyze data.

example:

CREATE TABLE MyTable
(
  ID INT IDENTITY PRIMARY KEY, 
  Foo INT
) 

CREATE NONCLUSTERED INDEX index1 ON MyTable(ID, Foo)

SELECT ID, Foo FROM MyTable -- All requested data are covered by index

This is one of the fastest methods to retrieve data from SQL server.


Covering indexes are indexes which "cover" all columns needed from a specific table, removing the need to access the physical table at all for a given query/ operation.

Since the index contains the desired columns (or a superset of them), table access can be replaced with an index lookup or scan -- which is generally much faster.

Columns to cover:

  • parameterized or static conditions; columns restricted by a parameterized or constant condition.
  • join columns; columns dynamically used for joining
  • selected columns; to answer selected values.

While covering indexes can often provide good benefit for retrieval, they do add somewhat to insert/ update overhead; due to the need to write extra or larger index rows on every update.

Covering indexes for Joined Queries

Covering indexes are probably most valuable as a performance technique for joined queries. This is because joined queries are more costly & more likely then single-table retrievals to suffer high cost performance problems.

  • in a joined query, covering indexes should be considered per-table.
  • each 'covering index' removes a physical table access from the plan & replaces it with index-only access.
  • investigate the plan costs & experiment with which tables are most worthwhile to replace by a covering index.
  • by this means, the multiplicative cost of large join plans can be significantly reduced.

For example:

select oi.title, c.name, c.address
from porderitem poi
join porder po on po.id = poi.fk_order
join customer c on c.id = po.fk_customer
where po.orderdate > ? and po.status = 'SHIPPING';

create index porder_custitem on porder (orderdate, id, status, fk_customer);

See:

  • http://literatejava.com/sql/covering-indexes-query-optimization/