What is a Covered Index?

SqlDatabaseIndexing

Sql Problem Overview


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

Sql Solutions


Solution 1 - Sql

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.

Solution 2 - Sql

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.

Solution 3 - Sql

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:

Solution 4 - Sql

Lets say you have a simple table with the below columns, you have only indexed Id here:

Id (Int), Telephone_Number (Int), Name (VARCHAR), Address (VARCHAR)

Imagine you have to run the below query and check whether its using index, and whether performing efficiently without I/O calls or not. Remember, you have only created an index on Id.

SELECT Id FROM mytable WHERE Telephone_Number = '55442233';

When you check for performance on this query you will be dissappointed, since Telephone_Number is not indexed this needs to fetch rows from table using I/O calls. So, this is not a covering indexed since there is some column in query which is not indexed, which leads to frequent I/O calls.

To make it a covered index you need to create a composite index on (Id, Telephone_Number).

For more details, please refer to this blog: https://www.percona.com/blog/2006/11/23/covering-index-and-prefix-indexes/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartynnwView Question on Stackoverflow
Solution 1 - SqlLasse V. KarlsenView Answer on Stackoverflow
Solution 2 - SqlakuView Answer on Stackoverflow
Solution 3 - SqlThomas WView Answer on Stackoverflow
Solution 4 - Sqluser4398985View Answer on Stackoverflow