From 3abcd9d3e2116656e4d26aa18e9c21e6791027ff Mon Sep 17 00:00:00 2001 From: Gabriel Hurley Date: Wed, 24 Nov 2010 11:52:15 +0000 Subject: [PATCH] Fixed #14767 -- Reflowed paragraphs and cleaned up some markup/links 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 --- docs/topics/db/optimization.txt | 39 ++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/docs/topics/db/optimization.txt b/docs/topics/db/optimization.txt index 7449d63c27..fda26f1744 100644 --- a/docs/topics/db/optimization.txt +++ b/docs/topics/db/optimization.txt @@ -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 `. 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 -`: +`:: >>> 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. +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. +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() `. Similarly, do :ref:`bulk deletes ` 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 `. +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 `. Use foreign key values directly -------------------------------