{"title":"データベースアクセスの最適化","version":"6.1","locale":"ja","docname":"topics/db/optimization","url":"/ja/6.1/topics/db/optimization/","canonical":"https://djangodocs.dev/ja/6.1/topics/db/optimization/","summary":"Djangoのデータベース層は、開発者がデータベースを最大限活用できるように、さまざまな方法を提供しています。このドキュメントでは、データベースアクセスを最適化する際にとるべき手順を、大まかにいくつかの見出しとしてまとめています。それぞれの見出しの下に、関連するドキュメントへのリンクを集約した上で、さまざまなヒントを追加していま…","html":"<h1>データベースアクセスの最適化<a class=\"heading-anchor\" href=\"#database-access-optimization\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Djangoのデータベース層は、開発者がデータベースを最大限活用できるように、さまざまな方法を提供しています。このドキュメントでは、データベースアクセスを最適化する際にとるべき手順を、大まかにいくつかの見出しとしてまとめています。それぞれの見出しの下に、関連するドキュメントへのリンクを集約した上で、さまざまなヒントを追加しています。</p>\n<section id=\"profile-first\">\n<h2>まずはプロファイルを取る<a class=\"heading-anchor\" href=\"#profile-first\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>一般的なプログラミングの習慣として、これは言うまでもありません。 <a class=\"reference internal\" href=\"/ja/6.1/faq/models/#faq-see-raw-sql-queries\"><span class=\"std std-ref\">どんなクエリを実行しているか、それにどれくらいのコストがかかっているかを確認してください</span></a> 。特定の <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> がデータベースによってどのように実行されるのかを理解するには、 <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.explain\" title=\"django.db.models.query.QuerySet.explain\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">QuerySet.explain()</span></code></a> を使用してください。また、 <a class=\"extlink-pypi reference external\" href=\"https://pypi.org/project/django-debug-toolbar/\">django-debug-toolbar</a> のような外部プロジェクトや、データベースを直接監視するツールを使用するのも良いでしょう。</p>\n<p>要件に従って、速度またはメモリ、およびその両方を最適化できます。片方を最適化することは、もう片方に悪影響を及ぼすことがありますが、互いに助けになることもあります。また、データベースプロセスによって行われる処理と Python のプロセスによる処理は (あなたにとって) 必ずしも同等のコストとはなりません。その優先順位とバランスを決めるのはあなた自身です。そして、その設計はアプリケーションやサーバーに依存するため、要求通りに設計するのもあなたの仕事です。</p>\n<p>以下で紹介する項目すべてにおいて、あらゆる変更の後に忘れずに分析を行い、施した変更が有益だったこと、およびその恩恵が可読性の低下を十分上回ることを確認してください。以下の <strong>すべて</strong> の提案において、一般的な原則があなたの状況に当てはまらない可能性があること、それどころか逆効果になりかねない可能性さえあることに十分注意してください。</p>\n</section>\n<section id=\"use-standard-db-optimization-techniques\">\n<h2>標準的な DB 最適化のテクニックを使う<a class=\"heading-anchor\" href=\"#use-standard-db-optimization-techniques\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>以下のようなものが上げられます:</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Database_index\">Indexes</a>. This is a number one priority, <em>after</em> you have determined from\nprofiling what indexes should be added. Use\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/options/#django.db.models.Options.indexes\" title=\"django.db.models.Options.indexes\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">Meta.indexes</span></code></a> or\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/fields/#django.db.models.Field.db_index\" title=\"django.db.models.Field.db_index\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">Field.db_index</span></code></a> to add these from\nDjango. Consider adding indexes to fields that you frequently query using\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">filter()</span></code></a>,\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.exclude\" title=\"django.db.models.query.QuerySet.exclude\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">exclude()</span></code></a>,\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.order_by\" title=\"django.db.models.query.QuerySet.order_by\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">order_by()</span></code></a>, etc. as indexes may help\nto speed up lookups. Note that determining the best indexes is a complex\ndatabase-dependent topic that will depend on your particular application.\nThe overhead of maintaining an index may outweigh any gains in query speed.</p></li>\n</ul>\n<ul class=\"simple\">\n<li><p>フィールドタイプの適切な使用。</p></li>\n</ul>\n<p>以降は、上記の明確な対処は実行済みだという前提で進めていきます。このドキュメントの残りの部分では、不要な作業をしなくて済むように、Django をどのように使えばいいかを中心に説明します。またこのドキュメントでは、<a class=\"reference internal\" href=\"/ja/6.1/topics/cache/\"><span class=\"doc\">汎用キャッシュ</span></a> のような高コストな最適化手法については説明しません。</p>\n</section>\n<section id=\"understand-querysets\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> を理解する<a class=\"heading-anchor\" href=\"#understand-querysets\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/\"><span class=\"doc\">QuerySet</span></a> を理解することは、シンプルなコードでパフォーマンスを上げるために極めて重要です。特に:</p>\n<section id=\"understand-queryset-evaluation\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> の評価を理解する<a class=\"heading-anchor\" href=\"#understand-queryset-evaluation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>パフォーマンスの問題を回避するには、以下を理解することが重要です:</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/ja/6.1/topics/db/queries/#querysets-are-lazy\"><span class=\"std std-ref\">QuerySet は遅延評価される</span></a> こと。</p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#when-querysets-are-evaluated\"><span class=\"std std-ref\">いつQuerySet が評価されるのか</span></a> 。</p></li>\n<li><p>どのように <a class=\"reference internal\" href=\"/ja/6.1/topics/db/queries/#caching-and-querysets\"><span class=\"std std-ref\">データがメモリ上に保持されるか</span></a>。</p></li>\n</ul>\n</section>\n<section id=\"understand-cached-attributes\">\n<h3>キャッシュされる属性を理解する<a class=\"heading-anchor\" href=\"#understand-cached-attributes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>クエリセット全体のキャッシュだけでなく、ORM オブジェクトの属性の結果のキャッシュもあります。通常、呼び出し可能でない属性はキャッシュされます。例えば、<a class=\"reference internal\" href=\"/ja/6.1/topics/db/queries/#queryset-model-example\"><span class=\"std std-ref\">例のブログモデル</span></a> においても:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">entry</span> <span class=\"o\">=</span> <span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">entry</span><span class=\"o\">.</span><span class=\"n\">blog</span>  <span class=\"c1\"># Blog object is retrieved at this point</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">entry</span><span class=\"o\">.</span><span class=\"n\">blog</span>  <span class=\"c1\"># cached version, no DB access</span>\n</code></pre></div>\n<p>しかし、一般に、呼び出し可能な属性は毎回DBルックアップを引き起こします:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">entry</span> <span class=\"o\">=</span> <span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">entry</span><span class=\"o\">.</span><span class=\"n\">authors</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>  <span class=\"c1\"># query performed</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">entry</span><span class=\"o\">.</span><span class=\"n\">authors</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>  <span class=\"c1\"># query performed again</span>\n</code></pre></div>\n<p>テンプレート上のコードを読む際には注意が必要です。テンプレートシステムは括弧を許容していませんが、呼び出し可能なオブジェクトは自動的に呼び出されるので、上記の区別が隠れてしまいます。</p>\n<p>独自のプロパティにも注意が必要です - 必要なときにキャッシングを実装するのはあなた次第です。たとえば <a class=\"reference internal\" href=\"/ja/6.1/ref/utils/#django.utils.functional.cached_property\" title=\"django.utils.functional.cached_property\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">cached_property</span></code></a> デコレータを使用します。</p>\n</section>\n<section id=\"use-the-with-template-tag\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">with</span></code> テンプレートタグを使用する<a class=\"heading-anchor\" href=\"#use-the-with-template-tag\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> のキャッシュ処理を活用するため、<a class=\"reference internal\" href=\"/ja/6.1/ref/templates/builtins/#std-templatetag-with\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">with</span></code></a> テンプレートタグの使用が推奨されます。</p>\n</section>\n<section id=\"use-iterator\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">iterator()</span></code> を使用する<a class=\"heading-anchor\" href=\"#use-iterator\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>When you have a lot of objects, the caching behavior of the <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> can\ncause a large amount of memory to be used. In this case,\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.iterator\" title=\"django.db.models.query.QuerySet.iterator\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">iterator()</span></code></a> may help.</p>\n</section>\n<section id=\"use-explain\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">explain()</span></code> を使用する<a class=\"heading-anchor\" href=\"#use-explain\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.explain\" title=\"django.db.models.query.QuerySet.explain\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">QuerySet.explain()</span></code></a> を使うと、使用されているインデックスや結合など、データベースがクエリをどのように実行しているのか、詳細な情報を得られます。この詳細情報は、より効率的になるようにクエリを書き換えたり、パフォーマンスを向上させるために追加できるインデックスを特定するのに役立ちます。</p>\n</section>\n</section>\n<section id=\"do-database-work-in-the-database-rather-than-in-python\">\n<h2>データベースの仕事を Python ではなくデータベースに行わせる<a class=\"heading-anchor\" href=\"#do-database-work-in-the-database-rather-than-in-python\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>例えば:</p>\n<ul class=\"simple\">\n<li><p>最も基本的なレベルでは、<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#queryset-api\"><span class=\"std std-ref\">filter や exclude</span></a> を使ってデータベース内でフィルタリングを行います。</p></li>\n<li><p>Use <a class=\"reference internal\" href=\"/ja/6.1/ref/models/expressions/#f-expressions\"><span class=\"std std-ref\">F() 式</span></a> to filter based on other fields within the same\nmodel.</p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/6.1/topics/db/aggregation/\"><span class=\"doc\">データベース内の集計をするためアノテーション</span></a> を使います。</p></li>\n</ul>\n<p>必要な SQL を生成するのに不十分な場合は:</p>\n<section id=\"use-rawsql\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">RawSQL</span></code> を使用する<a class=\"heading-anchor\" href=\"#use-rawsql\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>保守性は高くありませんが、より強力な方法は <a class=\"reference internal\" href=\"/ja/6.1/ref/models/expressions/#django.db.models.expressions.RawSQL\" title=\"django.db.models.expressions.RawSQL\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RawSQL</span></code></a> 表現です。これにより、SQL を明示的にクエリに追加できます。これでもまだ不十分な場合は:</p>\n</section>\n<section id=\"use-raw-sql\">\n<h3>素の SQL を使用する<a class=\"heading-anchor\" href=\"#use-raw-sql\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/ja/6.1/topics/db/sql/\"><span class=\"doc\">モデルの取り出しおよび書き込みをするためのカスタム SQL</span></a> を記述します。<code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.connection.queries</span></code> を使い、Django があなたのために何を書いているのかを理解して、そこから始めましょう。</p>\n</section>\n</section>\n<section id=\"retrieve-individual-objects-using-a-unique-indexed-column\">\n<h2>ユニークかつインデックス済みの列を使用して個別のオブジェクトを取得する<a class=\"heading-anchor\" href=\"#retrieve-individual-objects-using-a-unique-indexed-column\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>個々のオブジェクトを取得するために <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get()</span></code></a> を使用する際に、<a class=\"reference internal\" href=\"/ja/6.1/ref/models/fields/#django.db.models.Field.unique\" title=\"django.db.models.Field.unique\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">unique</span></code></a> や <a class=\"reference internal\" href=\"/ja/6.1/ref/models/fields/#django.db.models.Field.db_index\" title=\"django.db.models.Field.db_index\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">db_index</span></code></a> を持つカラムを使用する理由は2つあります。まず、データベースインデックスによりクエリが高速になります。また、ルックアップに一致するオブジェクトが複数ある場合、クエリは非常に遅くなる可能性があります。カラムに一意の制約を持つことで、これが決して起こらないことが保証されます。</p>\n<p>例えば、<a class=\"reference internal\" href=\"/ja/6.1/topics/db/queries/#queryset-model-example\"><span class=\"std std-ref\">例のブログモデル</span></a> を使うと:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">entry</span> <span class=\"o\">=</span> <span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>上記は以下よりも高速です:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">entry</span> <span class=\"o\">=</span> <span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;News Item Title&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>これは、<code class=\"docutils literal notranslate\"><span class=\"pre\">id</span></code> がデータベースによってインデックス化されていて、ユニークだと保証されているからです。</p>\n<p>以下のようにすると非常に遅くなる恐れがあります:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">entry</span> <span class=\"o\">=</span> <span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">headline__startswith</span><span class=\"o\">=</span><span class=\"s2\">&quot;News&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>まず第一に、<code class=\"docutils literal notranslate\"><span class=\"pre\">headline</span></code> はインデックス化されておらず、データベースのデータ取り出しを遅くします。</p>\n<p>Second, the lookup may return multiple results. Even though Django applies a\nlimit of 21 objects when using <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get()</span></code></a>,\nthe database may still need to scan everything to evaluate a non-unique\ncondition. Narrowing your query up-front is more efficient.</p>\n</section>\n<section id=\"retrieve-related-objects-efficiently\">\n<h2>Retrieve related objects efficiently<a class=\"heading-anchor\" href=\"#retrieve-related-objects-efficiently\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Generally, accessing the database multiple times to retrieve different parts\nof a single &quot;set&quot; of data is less efficient than retrieving it all in one\nquery. This is particularly important if you have a query that is executed in a\nloop, and could therefore end up doing many database queries, when only one\nis needed. Below are some techniques to combine queries for efficiency.</p>\n<section id=\"use-the-fetch-peers-fetch-mode\">\n<h3>Use the <code class=\"docutils literal notranslate\"><span class=\"pre\">FETCH_PEERS</span></code> fetch mode<a class=\"heading-anchor\" href=\"#use-the-fetch-peers-fetch-mode\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Use the <a class=\"reference internal\" href=\"/ja/6.1/topics/db/fetch-modes/#django.db.models.FETCH_PEERS\" title=\"django.db.models.FETCH_PEERS\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">FETCH_PEERS</span></code></a> fetch mode to make on-demand\nfield access more efficient with bulk-fetching. Enable it for all usage of\nyour models <a class=\"reference internal\" href=\"/ja/6.1/topics/db/fetch-modes/#fetch-modes-custom-manager\"><span class=\"std std-ref\">with a custom manager</span></a>.</p>\n<p>Using this fetch mode is easier than declaring fields to fetch with\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.select_related\" title=\"django.db.models.query.QuerySet.select_related\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">select_related()</span></code></a> or\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related\" title=\"django.db.models.query.QuerySet.prefetch_related\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">prefetch_related()</span></code></a>, especially when it's\nhard to predict which fields will be accessed.</p>\n</section>\n<section id=\"use-queryset-select-related-and-prefetch-related\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.select_related()</span></code> や <code class=\"docutils literal notranslate\"><span class=\"pre\">prefetch_related()</span></code> を使用する<a class=\"heading-anchor\" href=\"#use-queryset-select-related-and-prefetch-related\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>When the <a class=\"reference internal\" href=\"/ja/6.1/topics/db/fetch-modes/#django.db.models.FETCH_PEERS\" title=\"django.db.models.FETCH_PEERS\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">FETCH_PEERS</span></code></a> fetch mode is not appropriate or\nefficient enough, use <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.select_related\" title=\"django.db.models.query.QuerySet.select_related\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">select_related()</span></code></a>\nand <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related\" title=\"django.db.models.query.QuerySet.prefetch_related\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">prefetch_related()</span></code></a>. Understand their\ndocumentation thoroughly and apply them where needed.</p>\n<p>It may be useful to apply these methods in <a class=\"reference internal\" href=\"/ja/6.1/topics/db/managers/\"><span class=\"doc\">managers and default managers</span></a>. Be aware when your manager is and is not used; for\nexample, related object access <a class=\"reference internal\" href=\"/ja/6.1/topics/db/managers/#managers-for-related-objects\"><span class=\"std std-ref\">uses the base manager</span></a> rather than the default manager.</p>\n</section>\n<section id=\"use-prefetch-related-objects\">\n<h3>Use <code class=\"docutils literal notranslate\"><span class=\"pre\">prefetch_related_objects()</span></code><a class=\"heading-anchor\" href=\"#use-prefetch-related-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Where <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related\" title=\"django.db.models.query.QuerySet.prefetch_related\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">prefetch_related</span></code></a> would be useful\nafter the queryset has been evaluated, use\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.prefetch_related_objects\" title=\"django.db.models.prefetch_related_objects\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">prefetch_related_objects()</span></code></a> to execute an extra\nprefetch.</p>\n</section>\n</section>\n<section id=\"don-t-retrieve-things-you-don-t-need\">\n<h2>必要ないものを取り出さない<a class=\"heading-anchor\" href=\"#don-t-retrieve-things-you-don-t-need\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"use-queryset-values-and-values-list\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.values()</span></code> や <code class=\"docutils literal notranslate\"><span class=\"pre\">values_list()</span></code> を使用する<a class=\"heading-anchor\" href=\"#use-queryset-values-and-values-list\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>When you only want a <code class=\"docutils literal notranslate\"><span class=\"pre\">dict</span></code> or <code class=\"docutils literal notranslate\"><span class=\"pre\">list</span></code> of values, and don't need ORM model\nobjects, make appropriate usage of\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.values\" title=\"django.db.models.query.QuerySet.values\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">values()</span></code></a>.\nThese can be useful for replacing model objects in template code - as long as\nthe dicts you supply have the same attributes as those used in the template,\nyou are fine.</p>\n</section>\n<section id=\"use-queryset-defer-and-only\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.defer()</span></code> や <code class=\"docutils literal notranslate\"><span class=\"pre\">only()</span></code> を使用する<a class=\"heading-anchor\" href=\"#use-queryset-defer-and-only\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Use <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.defer\" title=\"django.db.models.query.QuerySet.defer\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">defer()</span></code></a> and\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.only\" title=\"django.db.models.query.QuerySet.only\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">only()</span></code></a> if there are database columns\nyou know that you won't need (or won't need in most cases) to avoid loading\nthem. Note that if you <em>do</em> use them, the ORM will have to go and get them in\na separate query, making this a pessimization if you use it inappropriately.</p>\n<p>プロファイリングなしに、あまり積極的にフィールドの遅延を行わないようにしてください。たとえ、いくつかのカラムしか使用しないことになったとしても、データベースは結果の1行のために、非テキスト、非 <code class=\"docutils literal notranslate\"><span class=\"pre\">VARCHAR</span></code> データのほとんどをディスクから読み込まなければならないからです。 <code class=\"docutils literal notranslate\"><span class=\"pre\">defer()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">only()</span></code> メソッドは、多くのテキストデータの読み込みを避けられる場合や、Python に戻すのに多くの処理が必要なフィールドに対して最も有効なメソッドです。いつものように、まずはプロファイルを作成し、次に最適化を行ってください。</p>\n</section>\n<section id=\"use-queryset-contains-obj\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.contains(obj)</span></code> を使用する<a class=\"heading-anchor\" href=\"#use-queryset-contains-obj\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>...単に <code class=\"docutils literal notranslate\"><span class=\"pre\">obj</span></code> がクエリセットに存在するかどうかを知りたいだけなら、 <code class=\"docutils literal notranslate\"><span class=\"pre\">if</span> <span class=\"pre\">obj</span> <span class=\"pre\">in</span> <span class=\"pre\">queryset</span></code> よりも適切です。</p>\n</section>\n<section id=\"use-queryset-count\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.count()</span></code> を使用する<a class=\"heading-anchor\" href=\"#use-queryset-count\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>...単に数を知りたいだけなら、 <code class=\"docutils literal notranslate\"><span class=\"pre\">len(queryset)</span></code> よりも適切です。</p>\n</section>\n<section id=\"use-queryset-exists\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.exists()</span></code> を使用する<a class=\"heading-anchor\" href=\"#use-queryset-exists\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>...単に1つ以上の結果が存在するかどうかを知りたいだけなら、 <code class=\"docutils literal notranslate\"><span class=\"pre\">if</span> <span class=\"pre\">queryset</span></code> よりも適切です。</p>\n<p>しかし:</p>\n</section>\n<section id=\"don-t-overuse-contains-count-and-exists\">\n<span id=\"overuse-of-count-and-exists\"></span><h3><code class=\"docutils literal notranslate\"><span class=\"pre\">contains()</span></code> 、 <code class=\"docutils literal notranslate\"><span class=\"pre\">count()</span></code> 、 <code class=\"docutils literal notranslate\"><span class=\"pre\">exists()</span></code> を使いすぎない<a class=\"heading-anchor\" href=\"#don-t-overuse-contains-count-and-exists\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>もしクエリセットの他のデータが必要になったときは、すぐに評価を行います。</p>\n<p>例えば、 <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> と多対多の関連をもつ <code class=\"docutils literal notranslate\"><span class=\"pre\">Group</span></code> モデルを考えたとき、以下のコードが最適です:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">members</span> <span class=\"o\">=</span> <span class=\"n\">group</span><span class=\"o\">.</span><span class=\"n\">members</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n\n<span class=\"k\">if</span> <span class=\"n\">display_group_members</span><span class=\"p\">:</span>\n    <span class=\"k\">if</span> <span class=\"n\">members</span><span class=\"p\">:</span>\n        <span class=\"k\">if</span> <span class=\"n\">current_user</span> <span class=\"ow\">in</span> <span class=\"n\">members</span><span class=\"p\">:</span>\n            <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;You and&quot;</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">members</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"s2\">&quot;other users are members of this group.&quot;</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;There are&quot;</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">members</span><span class=\"p\">),</span> <span class=\"s2\">&quot;members in this group.&quot;</span><span class=\"p\">)</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">member</span> <span class=\"ow\">in</span> <span class=\"n\">members</span><span class=\"p\">:</span>\n            <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">member</span><span class=\"o\">.</span><span class=\"n\">username</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;There are no members in this group.&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>最適である理由:</p>\n<ol class=\"arabic simple\">\n<li><p>クエリセットは遅延評価されるので、 <code class=\"docutils literal notranslate\"><span class=\"pre\">display_group_members</span></code> が <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> の場合、データベースクエリは発行されない</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">members</span></code> 変数に <code class=\"docutils literal notranslate\"><span class=\"pre\">group.members.all()</span></code> を格納することで、クエリ結果のキャッシュを再利用できる。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">if</span> <span class=\"pre\">members:</span></code> の行は <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.__bool__()</span></code> を呼び出すことになり、その結果、データベースで <code class=\"docutils literal notranslate\"><span class=\"pre\">group.members.all()</span></code> クエリが実行される。もし結果が無ければ <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> を返し、結果があれば <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> を返す。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">if</span> <span class=\"pre\">current_user</span> <span class=\"pre\">in</span> <span class=\"pre\">members:</span></code> の行は、結果のキャッシュにユーザーが含まれるかどうかを確認するので、新たなデータベースクエリは発行されない。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">len(members)</span></code> を使用することで <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.__len__()</span></code> が呼び出される。このとき、結果のキャッシュが再利用されるので、新たなデータベースクエリは発行されない。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">for</span> <span class=\"pre\">member</span></code> は結果のキャッシュを繰り返し処理する。</p></li>\n</ol>\n<p>このコードは合計で、データベースクエリを1回または0回実行します。ここで行った唯一の意図的な最適化は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">members</span></code> 変数を使用することです。もし <code class=\"docutils literal notranslate\"><span class=\"pre\">if</span></code> に対して <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.exists()</span></code> を使用したり、<code class=\"docutils literal notranslate\"><span class=\"pre\">in</span></code> に対して <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.contains()</span></code> を使用したり、<code class=\"docutils literal notranslate\"><span class=\"pre\">count</span></code> に対して <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.count()</span></code> を使用したりした場合、それぞれ追加のクエリが発生します。</p>\n</section>\n<section id=\"use-queryset-update-and-delete\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.update()</span></code> や <code class=\"docutils literal notranslate\"><span class=\"pre\">delete()</span></code> を使用する<a class=\"heading-anchor\" href=\"#use-queryset-update-and-delete\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>複数のオブジェクトを読み込んで値を設定し、それらを個別に保存するのではなく、<a class=\"reference internal\" href=\"/ja/6.1/topics/db/queries/#topics-db-queries-update\"><span class=\"std std-ref\">QuerySet.update()</span></a> を用いてSQLの一括UPDATE文を使用してください。同様に、可能であれば <a class=\"reference internal\" href=\"/ja/6.1/topics/db/queries/#topics-db-queries-delete\"><span class=\"std std-ref\">一括削除</span></a> を使用してください。</p>\n<p>ただし、これらの一括更新メソッドは、個々のインスタンスの <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> や <code class=\"docutils literal notranslate\"><span class=\"pre\">delete()</span></code> メソッドを呼び出すことはできないので、通常のデータベースオブジェクト <a class=\"reference internal\" href=\"/ja/6.1/ref/signals/\"><span class=\"doc\">シグナル</span></a> に由来するものを含め、これらのメソッドに追加した独自の処理は実行されないことに注意してください。</p>\n</section>\n<section id=\"use-foreign-key-values-directly\">\n<h3>外部キーの値を直接使用する<a class=\"heading-anchor\" href=\"#use-foreign-key-values-directly\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>外部キーの値だけが必要な場合は、関連するオブジェクト全体を取得してその主キーを取得するのではなく、すでに取得したオブジェクトにある外部キーの値を使います。つまり、次のように書きます。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">entry</span><span class=\"o\">.</span><span class=\"n\">blog_id</span>\n</code></pre></div>\n<p>次のようには書かないようにします。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">entry</span><span class=\"o\">.</span><span class=\"n\">blog</span><span class=\"o\">.</span><span class=\"n\">id</span>\n</code></pre></div>\n</section>\n<section id=\"don-t-order-results-if-you-don-t-care\">\n<h3>気にならないなら結果を並べ替えない<a class=\"heading-anchor\" href=\"#don-t-order-results-if-you-don-t-care\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Ordering is not free; each field to order by is an operation the database must\nperform. If a model has a default ordering (<a class=\"reference internal\" href=\"/ja/6.1/ref/models/options/#django.db.models.Options.ordering\" title=\"django.db.models.Options.ordering\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">Meta.ordering</span></code></a>) and you don't need it, remove\nit on a <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> by calling\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.order_by\" title=\"django.db.models.query.QuerySet.order_by\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">order_by()</span></code></a> with no parameters.</p>\n<p>データベースにインデックスを追加すると、並べ替えのパフォーマンスが向上する可能性があります。</p>\n</section>\n</section>\n<section id=\"use-bulk-methods\">\n<h2>一括メソッドを使用する<a class=\"heading-anchor\" href=\"#use-bulk-methods\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>SQL文の数を減らすために一括（bulk）メソッドを使用する</p>\n<section id=\"create-in-bulk\">\n<h3>一括で作成する<a class=\"heading-anchor\" href=\"#create-in-bulk\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>When creating objects, where possible, use the\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create\" title=\"django.db.models.query.QuerySet.bulk_create\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">bulk_create()</span></code></a> method to reduce the\nnumber of SQL queries. For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">bulk_create</span><span class=\"p\">(</span>\n    <span class=\"p\">[</span>\n        <span class=\"n\">Entry</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;This is a test&quot;</span><span class=\"p\">),</span>\n        <span class=\"n\">Entry</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;This is only a test&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>...これは下記よりも適切です:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;This is a test&quot;</span><span class=\"p\">)</span>\n<span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;This is only a test&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Note that <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create\" title=\"django.db.models.query.QuerySet.bulk_create\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">bulk_create()</span></code></a> has several\ncaveats, so ensure it's appropriate for your use case.</p>\n</section>\n<section id=\"update-in-bulk\">\n<h3>一括で更新する<a class=\"heading-anchor\" href=\"#update-in-bulk\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>When updating objects, where possible, use the\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.bulk_update\" title=\"django.db.models.query.QuerySet.bulk_update\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">bulk_update()</span></code></a> method to reduce the\nnumber of SQL queries. Given a list or queryset of objects:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">entries</span> <span class=\"o\">=</span> <span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">bulk_create</span><span class=\"p\">(</span>\n    <span class=\"p\">[</span>\n        <span class=\"n\">Entry</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;This is a test&quot;</span><span class=\"p\">),</span>\n        <span class=\"n\">Entry</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s2\">&quot;This is only a test&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>以下のような例を考えます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">entries</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">headline</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;This is not a test&quot;</span>\n<span class=\"n\">entries</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">headline</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;This is no longer a test&quot;</span>\n<span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">bulk_update</span><span class=\"p\">(</span><span class=\"n\">entries</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"s2\">&quot;headline&quot;</span><span class=\"p\">])</span>\n</code></pre></div>\n<p>...これは下記よりも適切です:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">entries</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">headline</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;This is not a test&quot;</span>\n<span class=\"n\">entries</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n<span class=\"n\">entries</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">headline</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;This is no longer a test&quot;</span>\n<span class=\"n\">entries</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Note that <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.bulk_update\" title=\"django.db.models.query.QuerySet.bulk_update\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">bulk_update()</span></code></a> has several\ncaveats, so ensure it's appropriate for your use case.</p>\n</section>\n<section id=\"insert-in-bulk\">\n<h3>一括で挿入する<a class=\"heading-anchor\" href=\"#insert-in-bulk\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/ja/6.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ManyToManyFields</span></code></a> にオブジェクトを追加するとき、可能であれば <a class=\"reference internal\" href=\"/ja/6.1/ref/models/relations/#django.db.models.fields.related.RelatedManager.add\" title=\"django.db.models.fields.related.RelatedManager.add\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">add()</span></code></a> を呼び出し、SQL文の数を減らしてください。例えば:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">my_band</span><span class=\"o\">.</span><span class=\"n\">members</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">me</span><span class=\"p\">,</span> <span class=\"n\">my_friend</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>...これは下記よりも適切です:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">my_band</span><span class=\"o\">.</span><span class=\"n\">members</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">me</span><span class=\"p\">)</span>\n<span class=\"n\">my_band</span><span class=\"o\">.</span><span class=\"n\">members</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">my_friend</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>……ここで、 <code class=\"docutils literal notranslate\"><span class=\"pre\">Band</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">Artist</span></code> は多対多のリレーションシップを持つモデル同士です。</p>\n<p>When inserting different pairs of objects into\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ManyToManyField</span></code></a> or when the custom\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/fields/#django.db.models.ManyToManyField.through\" title=\"django.db.models.ManyToManyField.through\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">through</span></code></a> table is defined, use\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create\" title=\"django.db.models.query.QuerySet.bulk_create\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">bulk_create()</span></code></a> method to reduce the\nnumber of SQL queries. For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">PizzaToppingRelationship</span> <span class=\"o\">=</span> <span class=\"n\">Pizza</span><span class=\"o\">.</span><span class=\"n\">toppings</span><span class=\"o\">.</span><span class=\"n\">through</span>\n<span class=\"n\">PizzaToppingRelationship</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">bulk_create</span><span class=\"p\">(</span>\n    <span class=\"p\">[</span>\n        <span class=\"n\">PizzaToppingRelationship</span><span class=\"p\">(</span><span class=\"n\">pizza</span><span class=\"o\">=</span><span class=\"n\">my_pizza</span><span class=\"p\">,</span> <span class=\"n\">topping</span><span class=\"o\">=</span><span class=\"n\">pepperoni</span><span class=\"p\">),</span>\n        <span class=\"n\">PizzaToppingRelationship</span><span class=\"p\">(</span><span class=\"n\">pizza</span><span class=\"o\">=</span><span class=\"n\">your_pizza</span><span class=\"p\">,</span> <span class=\"n\">topping</span><span class=\"o\">=</span><span class=\"n\">pepperoni</span><span class=\"p\">),</span>\n        <span class=\"n\">PizzaToppingRelationship</span><span class=\"p\">(</span><span class=\"n\">pizza</span><span class=\"o\">=</span><span class=\"n\">your_pizza</span><span class=\"p\">,</span> <span class=\"n\">topping</span><span class=\"o\">=</span><span class=\"n\">mushroom</span><span class=\"p\">),</span>\n    <span class=\"p\">],</span>\n    <span class=\"n\">ignore_conflicts</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>...これは下記よりも適切です:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">my_pizza</span><span class=\"o\">.</span><span class=\"n\">toppings</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">pepperoni</span><span class=\"p\">)</span>\n<span class=\"n\">your_pizza</span><span class=\"o\">.</span><span class=\"n\">toppings</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">pepperoni</span><span class=\"p\">,</span> <span class=\"n\">mushroom</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>ここで、 <code class=\"docutils literal notranslate\"><span class=\"pre\">Pizza</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">Topping</span></code> は多対多の関連を持っています。<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create\" title=\"django.db.models.query.QuerySet.bulk_create\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">このメソッド</span></code></a> には多くの注意事項があるので、自分のユースケースに適切であることを確認してください。</p>\n</section>\n<section id=\"remove-in-bulk\">\n<h3>一括で削除する<a class=\"heading-anchor\" href=\"#remove-in-bulk\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/ja/6.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ManyToManyFields</span></code></a> からオブジェクトを取り除くとき、可能であれば <a class=\"reference internal\" href=\"/ja/6.1/ref/models/relations/#django.db.models.fields.related.RelatedManager.remove\" title=\"django.db.models.fields.related.RelatedManager.remove\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">remove()</span></code></a> を呼び出し、SQL文の数を減らしてください。例えば:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">my_band</span><span class=\"o\">.</span><span class=\"n\">members</span><span class=\"o\">.</span><span class=\"n\">remove</span><span class=\"p\">(</span><span class=\"n\">me</span><span class=\"p\">,</span> <span class=\"n\">my_friend</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>...これは下記よりも適切です:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">my_band</span><span class=\"o\">.</span><span class=\"n\">members</span><span class=\"o\">.</span><span class=\"n\">remove</span><span class=\"p\">(</span><span class=\"n\">me</span><span class=\"p\">)</span>\n<span class=\"n\">my_band</span><span class=\"o\">.</span><span class=\"n\">members</span><span class=\"o\">.</span><span class=\"n\">remove</span><span class=\"p\">(</span><span class=\"n\">my_friend</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>……ここで、 <code class=\"docutils literal notranslate\"><span class=\"pre\">Band</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">Artist</span></code> は多対多のリレーションシップを持つモデル同士です。</p>\n<p>When removing multiple many-to-many relationships involving several instances\nof the related models, use the <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#django.db.models.query.QuerySet.delete\" title=\"django.db.models.query.QuerySet.delete\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">delete()</span></code></a>\nmethod on a filtered queryset of the field's\n<a class=\"reference internal\" href=\"/ja/6.1/ref/models/fields/#django.db.models.ManyToManyField.through\" title=\"django.db.models.ManyToManyField.through\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">through</span></code></a> model. By combining multiple\nconditions with <a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#q-objects\"><span class=\"std std-ref\">Q() オブジェクト</span></a>, you can delete several relationships in a\nsingle query. For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Q</span>\n\n<span class=\"n\">PizzaToppingRelationship</span> <span class=\"o\">=</span> <span class=\"n\">Pizza</span><span class=\"o\">.</span><span class=\"n\">toppings</span><span class=\"o\">.</span><span class=\"n\">through</span>\n<span class=\"n\">PizzaToppingRelationship</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span>\n    <span class=\"n\">Q</span><span class=\"p\">(</span><span class=\"n\">pizza</span><span class=\"o\">=</span><span class=\"n\">my_pizza</span><span class=\"p\">,</span> <span class=\"n\">topping</span><span class=\"o\">=</span><span class=\"n\">pepperoni</span><span class=\"p\">)</span>\n    <span class=\"o\">|</span> <span class=\"n\">Q</span><span class=\"p\">(</span><span class=\"n\">pizza</span><span class=\"o\">=</span><span class=\"n\">your_pizza</span><span class=\"p\">,</span> <span class=\"n\">topping</span><span class=\"o\">=</span><span class=\"n\">pepperoni</span><span class=\"p\">)</span>\n    <span class=\"o\">|</span> <span class=\"n\">Q</span><span class=\"p\">(</span><span class=\"n\">pizza</span><span class=\"o\">=</span><span class=\"n\">your_pizza</span><span class=\"p\">,</span> <span class=\"n\">topping</span><span class=\"o\">=</span><span class=\"n\">mushroom</span><span class=\"p\">)</span>\n<span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>...これは下記よりも適切です:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">my_pizza</span><span class=\"o\">.</span><span class=\"n\">toppings</span><span class=\"o\">.</span><span class=\"n\">remove</span><span class=\"p\">(</span><span class=\"n\">pepperoni</span><span class=\"p\">)</span>\n<span class=\"n\">your_pizza</span><span class=\"o\">.</span><span class=\"n\">toppings</span><span class=\"o\">.</span><span class=\"n\">remove</span><span class=\"p\">(</span><span class=\"n\">pepperoni</span><span class=\"p\">,</span> <span class=\"n\">mushroom</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>... ここで、 <code class=\"docutils literal notranslate\"><span class=\"pre\">Pizza</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">Topping</span></code> は多対多の関係です。</p>\n</section>\n</section>","rootId":"database-access-optimization","toc":[{"title":"まずはプロファイルを取る","anchor":"profile-first","children":[]},{"title":"標準的な DB 最適化のテクニックを使う","anchor":"use-standard-db-optimization-techniques","children":[]},{"title":"QuerySet を理解する","anchor":"understand-querysets","children":[{"title":"QuerySet の評価を理解する","anchor":"understand-queryset-evaluation","children":[]},{"title":"キャッシュされる属性を理解する","anchor":"understand-cached-attributes","children":[]},{"title":"with テンプレートタグを使用する","anchor":"use-the-with-template-tag","children":[]},{"title":"iterator() を使用する","anchor":"use-iterator","children":[]},{"title":"explain() を使用する","anchor":"use-explain","children":[]}]},{"title":"データベースの仕事を Python ではなくデータベースに行わせる","anchor":"do-database-work-in-the-database-rather-than-in-python","children":[{"title":"RawSQL を使用する","anchor":"use-rawsql","children":[]},{"title":"素の SQL を使用する","anchor":"use-raw-sql","children":[]}]},{"title":"ユニークかつインデックス済みの列を使用して個別のオブジェクトを取得する","anchor":"retrieve-individual-objects-using-a-unique-indexed-column","children":[]},{"title":"Retrieve related objects efficiently","anchor":"retrieve-related-objects-efficiently","children":[{"title":"Use the FETCH_PEERS fetch mode","anchor":"use-the-fetch-peers-fetch-mode","children":[]},{"title":"QuerySet.select_related() や prefetch_related() を使用する","anchor":"use-queryset-select-related-and-prefetch-related","children":[]},{"title":"Use prefetch_related_objects()","anchor":"use-prefetch-related-objects","children":[]}]},{"title":"必要ないものを取り出さない","anchor":"don-t-retrieve-things-you-don-t-need","children":[{"title":"QuerySet.values() や values_list() を使用する","anchor":"use-queryset-values-and-values-list","children":[]},{"title":"QuerySet.defer() や only() を使用する","anchor":"use-queryset-defer-and-only","children":[]},{"title":"QuerySet.contains(obj) を使用する","anchor":"use-queryset-contains-obj","children":[]},{"title":"QuerySet.count() を使用する","anchor":"use-queryset-count","children":[]},{"title":"QuerySet.exists() を使用する","anchor":"use-queryset-exists","children":[]},{"title":"contains() 、 count() 、 exists() を使いすぎない","anchor":"don-t-overuse-contains-count-and-exists","children":[]},{"title":"QuerySet.update() や delete() を使用する","anchor":"use-queryset-update-and-delete","children":[]},{"title":"外部キーの値を直接使用する","anchor":"use-foreign-key-values-directly","children":[]},{"title":"気にならないなら結果を並べ替えない","anchor":"don-t-order-results-if-you-don-t-care","children":[]}]},{"title":"一括メソッドを使用する","anchor":"use-bulk-methods","children":[{"title":"一括で作成する","anchor":"create-in-bulk","children":[]},{"title":"一括で更新する","anchor":"update-in-bulk","children":[]},{"title":"一括で挿入する","anchor":"insert-in-bulk","children":[]},{"title":"一括で削除する","anchor":"remove-in-bulk","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/6.1/topics/"},{"docname":"topics/db/index","title":"モデルとデータベース","url":"/ja/6.1/topics/db/"}],"prev":{"docname":"topics/db/tablespaces","title":"テーブル空間（tablespace）","url":"/ja/6.1/topics/db/tablespaces/"},"next":{"docname":"topics/db/instrumentation","title":"データベースの計測","url":"/ja/6.1/topics/db/instrumentation/"},"formats":{"html":"/ja/6.1/topics/db/optimization/","markdown":"/ja/6.1/topics/db/optimization.md","json":"/ja/6.1/topics/db/optimization.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/topics/db/optimization.txt","official":"https://docs.djangoproject.com/ja/6.1/topics/db/optimization/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}