|
@@ -13,7 +13,7 @@ Profile first
|
|
|
As general programming practice, this goes without saying. Find out :ref:`what
|
|
|
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
|
|
|
-'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
|
|
|
your requirements. Sometimes optimizing for one will be detrimental to the
|
|
@@ -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
|
|
|
be reversed.
|
|
|
|
|
|
+.. _django-debug-toolbar: http://robhudson.github.com/django-debug-toolbar/
|
|
|
+
|
|
|
Use standard DB optimization techniques
|
|
|
=======================================
|
|
|
|
|
|
...including:
|
|
|
|
|
|
* 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
|
|
|
- these from Django.
|
|
|
+ profiling what indexes should be added. Use
|
|
|
+ :attr:`django.db.models.Field.db_index` to add these from Django.
|
|
|
|
|
|
* Appropriate use of field types.
|
|
|
|
|
@@ -69,7 +71,7 @@ Understand cached attributes
|
|
|
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
|
|
|
cached. For example, assuming the :ref:`example Weblog models
|
|
|
-<queryset-model-example>`:
|
|
|
+<queryset-model-example>`::
|
|
|
|
|
|
>>> entry = Entry.objects.get(id=1)
|
|
|
>>> entry.blog # Blog object is retrieved at this point
|
|
@@ -156,11 +158,11 @@ Don't retrieve things you don't need
|
|
|
Use ``QuerySet.values()`` and ``values_list()``
|
|
|
-----------------------------------------------
|
|
|
|
|
|
-When you just want a dict/list of values, and don't need ORM model objects, make
|
|
|
-appropriate usage of :meth:`~django.db.models.QuerySet.values()`.
|
|
|
+When you just want a ``dict`` or ``list`` of values, and don't need ORM model
|
|
|
+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
|
|
|
-the dicts you supply have the same attributes as those used in the template, you
|
|
|
-are fine.
|
|
|
+the dicts you supply have the same attributes as those used in the template,
|
|
|
+you are fine.
|
|
|
|
|
|
Use ``QuerySet.defer()`` and ``only()``
|
|
|
---------------------------------------
|
|
@@ -168,10 +170,17 @@ Use ``QuerySet.defer()`` and ``only()``
|
|
|
Use :meth:`~django.db.models.QuerySet.defer()` and
|
|
|
: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
|
|
|
-them. Note that if you *do* use them, the ORM will have to go and get them in 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.
|
|
|
+them. Note that if you *do* use them, the ORM will have to go and get them in
|
|
|
+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.
|
|
|
|
|
|
Use QuerySet.count()
|
|
|
--------------------
|
|
@@ -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-delete>` where possible.
|
|
|
|
|
|
-Note, however, that these bulk update methods cannot call the ``save()`` or ``delete()``
|
|
|
-methods of individual instances, which means that any custom behaviour you have
|
|
|
-added for these methods will not be executed, including anything driven from the
|
|
|
-normal database object :doc:`signals </ref/signals>`.
|
|
|
+Note, however, that these bulk update methods cannot call the ``save()`` or
|
|
|
+``delete()`` methods of individual instances, which means that any custom
|
|
|
+behaviour you have added for these methods will not be executed, including
|
|
|
+anything driven from the normal database object :doc:`signals </ref/signals>`.
|
|
|
|
|
|
Use foreign key values directly
|
|
|
-------------------------------
|