Skip to content

Commit 64dc996

Browse files
committed
DOCS-956 indexes that cover queries
1 parent a85fc5b commit 64dc996

File tree

4 files changed

+104
-46
lines changed

4 files changed

+104
-46
lines changed

source/applications/indexes.txt

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -117,32 +117,52 @@ can support all the queries that search a "prefix" subset of those fields.
117117
Create Indexes that Support Covered Queries
118118
-------------------------------------------
119119

120-
A covered query is a query in which all the queried fields and
121-
the returned fields are part of an index; i.e.
120+
A covered query is a query in which:
122121

123122
- all the fields in the :ref:`query <read-operations-query-document>`
124-
are part of that index, **and**
123+
are part of an index, **and**
125124

126125
- all the fields returned in the results are in the same index.
127126

128-
Because the index "covers" the query, MongoDB can match the :ref:`query
129-
conditions <read-operations-query-document>` and return the results
130-
using only the index. MongoDB does not need to not look at documents
131-
outside of the index.
127+
Because the index "covers" the query, MongoDB can both match the
128+
:ref:`query conditions <read-operations-query-document>` **and** return
129+
the results using only the index; MongoDB does not need to look at
130+
documents outside of the index.
132131

133132
Querying *only* the index can be much faster than querying documents
134133
outside of the index. Index keys are typically smaller than the
135134
documents they catalog, and indexes are typically available in RAM or
136135
located sequentially on disk.
137136

138-
MongoDB automatically uses a covered query when possible. To ensure the
139-
use of a covered query, create an index that includes all the fields
140-
listed in the query result and the :ref:`query document
141-
<read-operations-query-document>`. This means that, if the index does
142-
**not** include the ``_id`` field, the :term:`projection` document
143-
given to a query (to specify which fields MongoDB returns from the
144-
result set) must explicitly exclude the ``_id`` field from the result
145-
set.
137+
MongoDB automatically uses an index that covers a query when possible.
138+
To ensure that a query is covered, create an index that includes all
139+
the fields listed in the query result and the :ref:`query document
140+
<read-operations-query-document>`. This means that if the index does
141+
**not** include the ``_id`` field, the :term:`projection` document,
142+
which specifies the fields MongoDB returns, must explicitly exclude the
143+
``_id`` field from the result set.
144+
145+
Consider the following example where the collection ``user`` has
146+
an index on the fields ``user`` and ``status``:
147+
148+
.. code-block:: javascript
149+
150+
{ status: 1, user: 1 }
151+
152+
Then, the following query which queries on the ``status`` field and
153+
returns only the ``user`` field is covered:
154+
155+
.. code-block:: javascript
156+
157+
db.users.find( { status: "A" }, { user: 1, _id: 0 } )
158+
159+
However, the following query that uses the index to match documents is
160+
**not** covered by the index because it returns both the ``user`` field
161+
**and** the ``_id`` field:
162+
163+
.. code-block:: javascript
164+
165+
db.users.find( { status: "A" }, { user: 1 } )
146166

147167
An index **cannot** cover a query if:
148168

@@ -180,10 +200,16 @@ An index **cannot** cover a query if:
180200

181201
db.users.find( { "user.login": "tester" }, { "user.login": 1, _id: 0 } )
182202

183-
To determine whether a query is covered, use :method:`explain()
184-
<cursor.explain()>`. If the output displays ``true`` for the
185-
``indexOnly`` field, the query is covered and MongoDB queried only the
186-
index. For more information see :ref:`indexes-measuring-use`.
203+
The query, however, does use the ``{ "user.login": 1 }`` index to
204+
find matching documents.
205+
206+
To determine whether a query is a covered query, use the
207+
:method:`~cursor.explain()` method. If the :method:`~cursor.explain()`
208+
output displays ``true`` for the :data:`indexOnly` field, the query is
209+
covered by an index, and MongoDB queries only that index to match the
210+
query **and** return the results.
211+
212+
For more information see :ref:`indexes-measuring-use`.
187213

188214
.. _index-sort:
189215
.. _sorting-with-indexes:

source/core/indexes.txt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,21 @@ MongoDB indexes have the following core features:
4646
with the best response time for each query type. You can override
4747
the query optimizer using the :method:`cursor.hint()` method.
4848

49-
- An index "covers" a query if the index keys store all the data that
50-
the query must return. When an index covers a query, the database
51-
returns results more quickly than for queries that have to scan many
52-
individual documents. See :ref:`indexes-covered-queries` for more
53-
information.
49+
- An index "covers" a query if:
50+
51+
- all the fields in the :ref:`query <read-operations-query-document>`
52+
are part of that index, **and**
53+
54+
- all the fields returned in the documents that match the query are
55+
in the same index.
56+
57+
When an index covers a query, the database can both match the
58+
:ref:`query conditions <read-operations-query-document>` **and**
59+
return the results using only the index; MongoDB does not need to
60+
look at documents outside of the index. Querying the index can be
61+
faster than querying the documents outside of the index.
62+
63+
See :ref:`indexes-covered-queries` for more information.
5464

5565
- Using queries with good index coverage reduces the number of full
5666
documents that MongoDB needs to store in memory, thus maximizing database

source/core/read-operations.txt

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -463,36 +463,48 @@ operation:
463463
Covering a Query
464464
~~~~~~~~~~~~~~~~
465465

466-
An index :ref:`covers <indexes-covered-queries>` a query when:
466+
An index :ref:`covers <indexes-covered-queries>` a query, or a query is
467+
a "covered" query, when:
467468

468469
- all the fields in the :ref:`query <read-operations-query-document>`
469470
are part of that index, **and**
470471

471472
- all the fields returned in the documents that match the query are in
472473
the same index.
473474

475+
When an index "covers" the query, MongoDB can both match the
476+
:ref:`query conditions <read-operations-query-document>` **and** return
477+
the results using only the index; MongoDB does not need to look at
478+
documents outside of the index. Querying the index can be faster than
479+
querying the documents outside of the index.
480+
474481
Consider the following example where the collection ``inventory`` has
475482
an index on the fields ``type`` and ``item``.
476483

477484
.. code-block:: sh
478485

479486
{ type: 1, item: 1 }
480487

481-
Then a query on the ``inventory`` collection that queries on the
482-
``type`` field and returns only the ``item`` field is covered by the
483-
index:
488+
Then the following query that queries on the ``type`` and ``item``
489+
fields and returns only the ``item`` field is covered by the ``{type:
490+
1, item: 1}`` index:
484491

485492
.. code-block:: javascript
486493

487-
db.inventory.find( { type: "food" },
494+
db.inventory.find( { type: "food", item:/^c/ },
488495
{ item: 1, _id: 0 } )
489496

490-
Because the index "covers" the query, MongoDB can match the :ref:`query
491-
conditions <read-operations-query-document>` and return the results
492-
using only the index. MongoDB does not need to look at documents
493-
outside of the index. Querying the index can be faster than querying
494-
the documents outside of the index. See :ref:`indexes-covered-queries`
495-
for more information, including when indexes cannot cover a query.
497+
However, the following query that uses the ``{ type: 1, item: 1 }`` index
498+
to match documents is **not** covered by the index because the query
499+
returns the ``item`` field **and** the ``_id`` field:
500+
501+
.. code-block:: javascript
502+
503+
db.inventory.find( { type: "food", item:/^c/ },
504+
{ item: 1 } )
505+
506+
See :ref:`indexes-covered-queries` for more information, including when
507+
indexes cannot cover a query.
496508

497509
Measuring Index Use
498510
~~~~~~~~~~~~~~~~~~~
@@ -588,11 +600,13 @@ the query used an index. This query:
588600
- then read 5 full documents from the collection, as indicated by
589601
the :data:`nscannedObjects` field.
590602

591-
Although the query used an index, the ``indexOnly: false`` indicates
592-
that the index did not :ref:`cover <read-operations-covered-query>`
593-
the query; i.e. MongoDB could not match the :ref:`query conditions
594-
<read-operations-query-document>` and return the results using only
595-
that index. See :ref:`indexes-covered-queries` for more information.
603+
Although the query uses an index to find the matching documents, the
604+
:data:`indexOnly:false <indexOnly>` indicates that this index did
605+
not :ref:`cover <read-operations-covered-query>` the query; i.e.
606+
MongoDB could not both match the :ref:`query conditions
607+
<read-operations-query-document>` **and** return the results using
608+
only this index. See :ref:`indexes-covered-queries` for more
609+
information.
596610

597611
.. index:: query optimizer
598612
.. _read-operations-query-optimization:

source/reference/explain.txt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,17 @@ Core Explain Output
155155

156156
Specifies the total number of documents scanned during the query.
157157
The :data:`nscannedObjects` may be lower than :data:`nscanned`, such
158-
as if the index is a covered index.
158+
as if the index :ref:`covers <indexes-covered-queries>` a query. See
159+
:data:`indexOnly`.
159160

160161
.. data:: nscanned
161162

162163
Specifies the total number of documents or index entries scanned
163164
during the database operation. You want :data:`n` and
164165
:data:`nscanned` to be close in value as possible. The
165166
:data:`nscanned` value may be higher than the
166-
:data:`nscannedObjects` value, such as if the index is a covered
167-
index.
167+
:data:`nscannedObjects` value, such as if the index :ref:`covers
168+
<indexes-covered-queries>` a query. See :data:`indexOnly`.
168169

169170
.. data:: nscannedObjectsAllPlans
170171

@@ -194,9 +195,16 @@ Core Explain Output
194195
.. data:: indexOnly
195196

196197
:data:`indexOnly` is a boolean value that returns ``true`` when the
197-
query is :ref:`covered <indexes-covered-queries>` by the index. In
198-
*covered* queries, the index contains all data that MongoDB needs
199-
to fulfill the query.
198+
the query is :ref:`covered <indexes-covered-queries>` by the index
199+
indicated in the :data:`cursor` field. When an index covers a query,
200+
MongoDB can both match the :ref:`query conditions
201+
<read-operations-query-document>` **and** return the results using
202+
only the index because:
203+
204+
- all the fields in the :ref:`query
205+
<read-operations-query-document>` are part of that index, **and**
206+
207+
- all the fields returned in the results set are in the same index.
200208

201209
.. data:: nYields
202210

0 commit comments

Comments
 (0)