Skip to content

Commit

Permalink
Fixed #14767 -- Reflowed paragraphs and cleaned up some markup/links …
Browse files Browse the repository at this point in the history
…in the topics/db/optimizations docs. Thanks to adamv for the report and patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14690 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
Gabriel Hurley committed Nov 24, 2010
1 parent 4c51986 commit 3abcd9d
Showing 1 changed file with 25 additions and 16 deletions.
41 changes: 25 additions & 16 deletions docs/topics/db/optimization.txt
Expand Up @@ -13,7 +13,7 @@ Profile first
As general programming practice, this goes without saying. Find out :ref:`what As general programming practice, this goes without saying. Find out :ref:`what
queries you are doing and what they are costing you queries you are doing and what they are costing you
<faq-see-raw-sql-queries>`. You may also want to use an external project like <faq-see-raw-sql-queries>`. You may also want to use an external project like
'django-debug-toolbar', or a tool that monitors your database directly. django-debug-toolbar_, or a tool that monitors your database directly.


Remember that you may be optimizing for speed or memory or both, depending on Remember that you may be optimizing for speed or memory or both, depending on
your requirements. Sometimes optimizing for one will be detrimental to the your requirements. Sometimes optimizing for one will be detrimental to the
Expand All @@ -29,14 +29,16 @@ readability of your code. **All** of the suggestions below come with the caveat
that in your circumstances the general principle might not apply, or might even that in your circumstances the general principle might not apply, or might even
be reversed. be reversed.


.. _django-debug-toolbar: http://robhudson.github.com/django-debug-toolbar/

Use standard DB optimization techniques Use standard DB optimization techniques
======================================= =======================================


...including: ...including:


* Indexes. This is a number one priority, *after* you have determined from * Indexes. This is a number one priority, *after* you have determined from
profiling what indexes should be added. Use :attr:`django.db.models.Field.db_index` to add profiling what indexes should be added. Use
these from Django. :attr:`django.db.models.Field.db_index` to add these from Django.


* Appropriate use of field types. * Appropriate use of field types.


Expand Down Expand Up @@ -69,7 +71,7 @@ Understand cached attributes
As well as caching of the whole ``QuerySet``, there is caching of the result of As well as caching of the whole ``QuerySet``, there is caching of the result of
attributes on ORM objects. In general, attributes that are not callable will be attributes on ORM objects. In general, attributes that are not callable will be
cached. For example, assuming the :ref:`example Weblog models cached. For example, assuming the :ref:`example Weblog models
<queryset-model-example>`: <queryset-model-example>`::


>>> entry = Entry.objects.get(id=1) >>> entry = Entry.objects.get(id=1)
>>> entry.blog # Blog object is retrieved at this point >>> entry.blog # Blog object is retrieved at this point
Expand Down Expand Up @@ -156,22 +158,29 @@ Don't retrieve things you don't need
Use ``QuerySet.values()`` and ``values_list()`` Use ``QuerySet.values()`` and ``values_list()``
----------------------------------------------- -----------------------------------------------


When you just want a dict/list of values, and don't need ORM model objects, make When you just want a ``dict`` or ``list`` of values, and don't need ORM model
appropriate usage of :meth:`~django.db.models.QuerySet.values()`. objects, make appropriate usage of :meth:`~django.db.models.QuerySet.values()`.
These can be useful for replacing model objects in template code - as long as These can be useful for replacing model objects in template code - as long as
the dicts you supply have the same attributes as those used in the template, you the dicts you supply have the same attributes as those used in the template,
are fine. you are fine.


Use ``QuerySet.defer()`` and ``only()`` Use ``QuerySet.defer()`` and ``only()``
--------------------------------------- ---------------------------------------


Use :meth:`~django.db.models.QuerySet.defer()` and Use :meth:`~django.db.models.QuerySet.defer()` and
:meth:`~django.db.models.QuerySet.only()` if there are database columns you :meth:`~django.db.models.QuerySet.only()` if there are database columns you
know that you won't need (or won't need in most cases) to avoid loading know that you won't need (or won't need in most cases) to avoid loading
them. Note that if you *do* use them, the ORM will have to go and get them in a them. Note that if you *do* use them, the ORM will have to go and get them in
separate query, making this a pessimization if you use it inappropriately. a separate query, making this a pessimization if you use it inappropriately.


Also, be aware that there is some (small extra) overhead incurred inside Django when constructing a model with deferred fields. Don't be too aggressive in deferring fields without profiling as the database has to read most of the non-text, non-VARCHAR data from the disk for a single row in the results, even if it ends up only using a few columns. The `defer()` and `only()` methods are most useful when you can avoid loading a lot of text data or for fields that might take a lot of processing to convert back to Python. As always, profile first, then optimize. Also, be aware that there is some (small extra) overhead incurred inside
Django when constructing a model with deferred fields. Don't be too aggressive
in deferring fields without profiling as the database has to read most of the
non-text, non-VARCHAR data from the disk for a single row in the results, even
if it ends up only using a few columns. The ``defer()`` and ``only()`` methods
are most useful when you can avoid loading a lot of text data or for fields
that might take a lot of processing to convert back to Python. As always,
profile first, then optimize.


Use QuerySet.count() Use QuerySet.count()
-------------------- --------------------
Expand Down Expand Up @@ -240,10 +249,10 @@ individual, use a bulk SQL UPDATE statement, via :ref:`QuerySet.update()
<topics-db-queries-update>`. Similarly, do :ref:`bulk deletes <topics-db-queries-update>`. Similarly, do :ref:`bulk deletes
<topics-db-queries-delete>` where possible. <topics-db-queries-delete>` where possible.


Note, however, that these bulk update methods cannot call the ``save()`` or ``delete()`` Note, however, that these bulk update methods cannot call the ``save()`` or
methods of individual instances, which means that any custom behaviour you have ``delete()`` methods of individual instances, which means that any custom
added for these methods will not be executed, including anything driven from the behaviour you have added for these methods will not be executed, including
normal database object :doc:`signals </ref/signals>`. anything driven from the normal database object :doc:`signals </ref/signals>`.


Use foreign key values directly Use foreign key values directly
------------------------------- -------------------------------
Expand Down

0 comments on commit 3abcd9d

Please sign in to comment.