Skip to content

DOCS-665 new optimization page #451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 14, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions source/administration/configuration.txt
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,9 @@ needed:
- :setting:`slowms` configures the threshold for the :term:`database
profiler` to consider a query "slow." The default value is 100
milliseconds. Set a lower value if the database profiler does not
return useful results. See the ":wiki:`Optimization`" wiki page
return useful results. See :doc:`/applications/optimization`
for more information on optimizing operations in MongoDB.

.. STUB ":doc:`/applications/optimization`"

- :setting:`profile` sets the :term:`database profiler`
level. The profiler is not active by default because of the possible
impact on the profiler itself on performance. Unless this setting
Expand Down
4 changes: 1 addition & 3 deletions source/administration/monitoring.txt
Original file line number Diff line number Diff line change
Expand Up @@ -405,12 +405,10 @@ This returns all operations that lasted longer than 100 milliseconds.
Ensure that the value specified here (i.e. ``100``) is above the
:setting:`slowms` threshold.

.. seealso:: The :wiki:`Optimization` wiki page addresses strategies
.. seealso:: :doc:`/applications/optimization` addresses strategies
that may improve the performance of your database queries and
operations.

.. STUB :doc:`/applications/optimization`

.. _replica-set-monitoring:

Replication and Monitoring
Expand Down
4 changes: 4 additions & 0 deletions source/applications/aggregation.txt
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ The aggregation operation in the previous section returns a
As a document, the result is subject to the :ref:`BSON
Document size <limit-bson-document-size>` limit, which is currently 16 megabytes.

.. _aggregation-optimize-performance:

Optimizing Performance
----------------------

Expand All @@ -179,6 +181,8 @@ Because you will always call :method:`aggregate` on a
the aggregation pipeline, you may want to optimize the operation
by avoiding scanning the entire collection whenever possible.

.. _aggregation-pipeline-operators-and-performance:

Pipeline Operators and Indexes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
174 changes: 174 additions & 0 deletions source/applications/optimization.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
============
Optimization
============

.. default-domain:: mongodb

This section describes techniques for optimizing database performance.

.. seealso:: :ref:`aggregation-optimize-performance`

Use Indexes
-----------

For commonly issued queries, create :doc:`indexes </indexes>`. If a
query searches multiple fields, create a :ref:`compound index
<index-type-compound>`. Scanning an index is much faster than scanning a
collection. Items in an index are ordered and smaller than the documents
they summarize.

.. example:: If you have a ``posts`` collection containing blog posts,
and if you regularly issue a query that sorts on the ``author_name``
field, then you can optimize the query by creating an index on the
``author_name`` field:

.. code-block:: javascript

db.posts.ensureIndex( { author_name : 1 } )

Indexes also improve efficiency on queries that routinely sort on a
given field.

.. example:: If you regularly issue a query that sorts on the
``timestamp`` field, then you can optimize the query by creating an
index on the ``timestamp`` field:

Creating this index:

.. code-block:: javascript

db.posts.ensureIndex( { timestamp : 1 } )

Optimizes this query:

.. code-block:: javascript

db.posts.find().sort( { timestamp : -1 } )

Direction on a single-key index does not matter. You can store the index
in either direction.

In certain cases, indexes speed performance for fields used by
aggregation operators. See
:ref:`aggregation-pipeline-operators-and-performance` for more
information.

Limit Results
-------------

MongoDB :term:`cursors <cursor>` return results in groups of multiple
documents. If you know the number of results you want, you can reduce
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sort of? cursors are iterables/generators? so this is more a driver tunable, as you set up.

the optimization that you want to talk about is reducing network traffic when you know you only want a certain number of results. Typically. used in conjunction with sort operations as in the following?

the demand on network resources by issuing the :method:`cursor.limit()`
method.

This is typically used in conjunction with sort operations. For example,
if you need only 10 results from your query to the ``posts``
collection, you would issue the following command:

.. code-block:: javascript

db.posts.find().sort( { timestamp : -1 } ).limit(10)

For more information on limiting results, see :method:`cursor.limit()`

Use Projections to Return Only Necessary Data
---------------------------------------------

When you need only a subset of fields from documents, you can achieve better
performance by returning only the fields you need:

For example, if in your query to the ``posts`` collection, you need only
the ``timestamp``, ``title``, ``author``, and ``abstract`` fields, you
would issue the following command:

.. code-block:: javascript

db.posts.find( {}, { timestamp : 1 , title : 1 , author : 1 , abstract : 1} ).sort( { timestamp : -1 } )

For more information on using projections, see
:ref:`read-operations-projection`.

Use the Database Profiler to Evaluate Performance
-------------------------------------------------

.. todo Add link below: :doc:`database profiler </tutorial/manage-the-database-profiler>`

MongoDB provides a database profiler that shows performance
characteristics of each operation against the database. Use the profiler
to locate any queries or write operations that are running slow. You can
use this information, for example, to determine what indexes to create.

.. todo Add below: , see :doc:`/tutorial/manage-the-database-profiler` and ...

For more information, see :ref:`database-profiling`.

Use db.currentOp() to Evaluate Performance
------------------------------------------

The :method:`db.currentOp()` method reports on current operations
running on a :program:`mongod` instance. For more information, see
:doc:`/reference/current-op`.

Use $explain to Evaluate Performance
------------------------------------

Use :method:`explain <cursor.explain()>` to return statistics on the
query, including what index MongoDB selected to fulfill the query.

.. todo Link to Kay's new explain doc

Use $hint to Select a Particular Index
--------------------------------------

In most cases the :ref:`query optimizer
<read-operations-query-optimization>` selects the best index. But
:method:`hint <cursor.hint()>` might help when you query on multiple
fields that are indexed in separate indexes. You can :method:`hint
<cursor.hint()>` to specify the index to use, potentially improving
performance.

Use the Increment Operator to Perform Operations Server-Side
------------------------------------------------------------

Use MongoDB's :operator:`$inc` operator to increment fields. The
operator increments fields on the server side, which can be much faster
than updating a document on the client side. Specifically, using
:operator:`$inc` is much faster than selecting a document, incrementing
a field in your application, and then writing the entire document back
to the server.

The :operator:`$inc` operator also avoids race conditions, as would
occur if two threads simultaneously queried for a document, manually
incremented a field, and saved the entire document back.

Perform Server-Side Code Execution
----------------------------------

Occasionally, for maximum performance, you might want to perform an
operation on the database server to eliminate client/server network
turnarounds. For example, if you want to remove a field from all
documents in a collection, performing the operation directly on the
server is more efficient than transmitting the collection to your client
and back again.

For more information, see :wiki:`Server-side Code Execution <Server-side+Code+Execution>`.

Use Capped Collections
----------------------

:doc:`/core/capped-collections` are circular, fixed-size collections that
keep documents well-ordered, even without the use of an index. This
means that capped collections can receive very high-speed writes and
sequential reads.

These collections are particularly useful for keeping log files but are
not limited to that purpose. Use capped collections where appropriate.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for keeping log-file type data?


Use Natural Order
-----------------

To return documents in the order they exist on disk, use the
:operator:`$natural` operator. :term:`Natural order <natural order>`
does not use indexes but can be fast for operations where the first or
last items on disk are required, particularly to operations on capped
collections.
3 changes: 2 additions & 1 deletion source/core/indexes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ MongoDB indexes have the following core features:
these representation of the data to optimize query responses.

- Every query, including update operations, use one and only one
index. The query optimizer selects the index empirically by
index. The :ref:`query optimizer <read-operations-query-optimization>`
selects the index empirically by
occasionally running alternate query plans and by selecting the plan
with the best response time for each query type. You can override
the query optimizer using the :method:`cursor.hint()` method.
Expand Down
3 changes: 2 additions & 1 deletion source/faq/indexes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ documentation on choosing which fields to index, see
:doc:`/applications/indexes`.

.. todo:: FAQ How do I guarantee a query uses an index?
MongoDB's query optimizer always looks for the most advantageous
MongoDB's :ref:`query optimizer <read-operations-query-optimization>`
always looks for the most advantageous
index to use. You cannot guarantee use of a particular index, but you
can write indexes with your queries in mind. For detailed
documentation on creating optimal indexes, see
Expand Down
6 changes: 4 additions & 2 deletions source/reference/glossary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -878,8 +878,10 @@ Glossary
For each query, the MongoDB query optimizer generates a query plan
that matches the query to the index that produces the fastest
results. The optimizer then uses the query plan each time the
:program:`mongod` receives the query. If a collection changes significantly, the optimizer
creates a new query plan.
:program:`mongod` receives the query. If a collection changes
significantly, the optimizer creates a new query plan.

.. seealso:: :ref:`read-operations-query-optimization`

diagnostic log
:program:`mongod` can create a verbose log of operations with
Expand Down
2 changes: 1 addition & 1 deletion source/reference/operator/hint.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ $hint

.. operator:: $hint

Use the :operator:`$hint` operator to force the query optimizer to
Use the :operator:`$hint` operator to force the :ref:`query optimizer <read-operations-query-optimization>` to
use a specific index to fulfill the query. Use :operator:`$hint`
for testing query performance and indexing strategies. Consider
the following form:
Expand Down