{"title":"Optimisasi akses basisdata","version":"1.10","locale":"id","docname":"topics/db/optimization","url":"/id/1.10/topics/db/optimization/","canonical":"https://djangodocs.dev/id/1.10/topics/db/optimization/","summary":"Django's database layer provides various ways to help developers get the most out of their databases. This document gathers together links to the relevant…","html":"<h1>Optimisasi akses basisdata<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's database layer provides various ways to help developers get the most\nout of their databases. This document gathers together links to the relevant\ndocumentation, and adds various tips, organized under a number of headings that\noutline the steps to take when attempting to optimize your database usage.</p>\n<section id=\"profile-first\">\n<h2>Profil dahulu<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>As general programming practice, this goes without saying. Find out <a class=\"reference internal\" href=\"/id/1.10/faq/models/#faq-see-raw-sql-queries\"><span class=\"std std-ref\">what\nqueries you are doing and what they are costing you</span></a>. You may also want to use an external project like\n<a class=\"reference external\" href=\"https://github.com/django-debug-toolbar/django-debug-toolbar/\">django-debug-toolbar</a>, or a tool that monitors your database directly.</p>\n<p>Remember that you may be optimizing for speed or memory or both, depending on\nyour requirements. Sometimes optimizing for one will be detrimental to the\nother, but sometimes they will help each other. Also, work that is done by the\ndatabase process might not have the same cost (to you) as the same amount of\nwork done in your Python process. It is up to you to decide what your\npriorities are, where the balance must lie, and profile all of these as required\nsince this will depend on your application and server.</p>\n<p>Dengan apapun yang mengikuti, ingat untuk menggambarkan raut muka setelah setiap perubahan untuk memastikan bahwa perubahan adalah menguntungkan, dan keuntungan cukup besar diberikan menurunkan dalam kesiapan kode anda. <strong>Semua</strong> dari saran-saran dibawah datang dengan surat keberatan yang dalam keadaan anda prinsip umum mungkin tidak berlaku, atau mungkin bahkan dibalikkan.</p>\n</section>\n<section id=\"use-standard-db-optimization-techniques\">\n<h2>Gunakan teknik-teknik optimalisasi DB standar<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>...termasuk:</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=\"/id/1.10/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> or\n<a class=\"reference internal\" href=\"/id/1.10/ref/models/options/#django.db.models.Options.index_together\" title=\"django.db.models.Options.index_together\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">Meta.index_together</span></code></a> to add\nthese from Django. Consider adding indexes to fields that you frequently\nquery using <a class=\"reference internal\" href=\"/id/1.10/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=\"/id/1.10/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=\"/id/1.10/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>Penggunaan sesuai dari jenis-jenis bidang</p></li>\n</ul>\n<p>We will assume you have done the obvious things above. The rest of this document\nfocuses on how to use Django in such a way that you are not doing unnecessary\nwork. This document also does not address other optimization techniques that\napply to all expensive operations, such as <a class=\"reference internal\" href=\"/id/1.10/topics/cache/\"><span class=\"doc\">general purpose caching</span></a>.</p>\n</section>\n<section id=\"understand-querysets\">\n<h2>Memahami <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>Memahami <a class=\"reference internal\" href=\"/id/1.10/ref/models/querysets/\"><span class=\"doc\">QuerySets</span></a> adalah vital untuk mendapatkan penampilan baik dengan kode sederhana. Khususnya:</p>\n<section id=\"understand-queryset-evaluation\">\n<h3>Memahami penilaian <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>Untuk menghindari masalah penampilan, sangatlah penting memahami:</p>\n<ul class=\"simple\">\n<li><p>itu <a class=\"reference internal\" href=\"/id/1.10/topics/db/queries/#querysets-are-lazy\"><span class=\"std std-ref\">QuerySets malas</span></a>.</p></li>\n<li><p>ketika <a class=\"reference internal\" href=\"/id/1.10/ref/models/querysets/#when-querysets-are-evaluated\"><span class=\"std std-ref\">mereka dinilai</span></a>.</p></li>\n<li><p>bagaimana <a class=\"reference internal\" href=\"/id/1.10/topics/db/queries/#caching-and-querysets\"><span class=\"std std-ref\">data ditahan dalam memori</span></a>.</p></li>\n</ul>\n</section>\n<section id=\"understand-cached-attributes\">\n<h3>Memahami atribut tembolok<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>As well as caching of the whole <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>, there is caching of the result of\nattributes on ORM objects. In general, attributes that are not callable will be\ncached. For example, assuming the <a class=\"reference internal\" href=\"/id/1.10/topics/db/queries/#queryset-model-example\"><span class=\"std std-ref\">example Weblog models</span></a>:</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=\"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>Tetapi secara umum, atribut callable menyebabkan pencarian DB setiap waktu:</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=\"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>Hati-hati ketika membaca kode cetakan - sistem cetakan tidak mengizinkan penggunaan tanda kurun, tetapi akan memanggil callable secara otomatis, memnyembunyikan perbedaan diatas.</p>\n<p>Be careful with your own custom properties - it is up to you to implement\ncaching when required, for example using the\n<a class=\"reference internal\" href=\"/id/1.10/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> decorator.</p>\n</section>\n<section id=\"use-the-with-template-tag\">\n<h3>Gunakan etiket cetakan <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>Untuk menggunakan perilaku cache dari <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>, anda mungkin butuh menggunakan etiket cetakan  <a class=\"reference internal\" href=\"/id/1.10/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>Gunakan <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>Ketika anda mempunyai banyak obyek, perilaku cache dari <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> dapat menyebabkan sejumlah besar memori digunakan. Dalam kasus ini, <a class=\"reference internal\" href=\"/id/1.10/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> mungkin membantu.</p>\n</section>\n</section>\n<section id=\"do-database-work-in-the-database-rather-than-in-python\">\n<h2>Lakukan pekerjaan basisdata di basisdata daripada di 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>Sebagai contoh:</p>\n<ul class=\"simple\">\n<li><p>Pada paling tingkat dasar, gunakan <a class=\"reference internal\" href=\"/id/1.10/ref/models/querysets/#queryset-api\"><span class=\"std std-ref\">filter and exclude</span></a> melakukan penyaringan di basisdata</p></li>\n<li><p>Gunakan <a class=\"reference internal\" href=\"/id/1.10/ref/models/expressions/#django.db.models.F\" title=\"django.db.models.F\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">F</span> <span class=\"pre\">expressions</span></code></a> untukmenyaring berdasarkan pada bidang-bidang lain dalam model sama.</p></li>\n<li><p>Gunakan <a class=\"reference internal\" href=\"/id/1.10/topics/db/aggregation/\"><span class=\"doc\">annotate to do aggregation in the database</span></a>.</p></li>\n</ul>\n<p>Jika ini tidak cukup membangkitkan SQL yang anda butuhkan:</p>\n<section id=\"use-rawsql\">\n<h3>Gunakan <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 less portable but more powerful method is the\n<a class=\"reference internal\" href=\"/id/1.10/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> expression, which allows some SQL\nto be explicitly added to the query. If that still isn't powerful enough:</p>\n</section>\n<section id=\"use-raw-sql\">\n<h3>Gunakan SQL mentah<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>Write your own <a class=\"reference internal\" href=\"/id/1.10/topics/db/sql/\"><span class=\"doc\">custom SQL to retrieve data or populate models</span></a>. Use <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.connection.queries</span></code> to find out what Django\nis writing for you and start from there.</p>\n</section>\n</section>\n<section id=\"retrieve-individual-objects-using-a-unique-indexed-column\">\n<h2>Mengambil obyek tersendiri menggukan sebuah unik, kolom indeks<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>There are two reasons to use a column with\n<a class=\"reference internal\" href=\"/id/1.10/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> or\n<a class=\"reference internal\" href=\"/id/1.10/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> when using\n<a class=\"reference internal\" href=\"/id/1.10/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> to retrieve individual objects.\nFirst, the query will be quicker because of the underlying database index.\nAlso, the query could run much slower if multiple objects match the lookup;\nhaving a unique constraint on the column guarantees this will never happen.</p>\n<p>Jadi menggunakan <a class=\"reference internal\" href=\"/id/1.10/topics/db/queries/#queryset-model-example\"><span class=\"std std-ref\">example Weblog models</span></a>:</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=\"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>akan lebih cepat daripada:</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=\"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>karena <code class=\"docutils literal notranslate\"><span class=\"pre\">id</span></code> diindeks oleh basisdata dan dijamin menjadi unik.</p>\n<p>Melakukan berikut berpotensi sangat lambat:</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=\"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>First of all, <code class=\"docutils literal notranslate\"><span class=\"pre\">headline</span></code> is not indexed, which will make the underlying\ndatabase fetch slower.</p>\n<p>Second, the lookup doesn't guarantee that only one object will be returned.\nIf the query matches more than one object, it will retrieve and transfer all of\nthem from the database. This penalty could be substantial if hundreds or\nthousands of records are returned. The penalty will be compounded if the\ndatabase lives on a separate server, where network overhead and latency also\nplay a factor.</p>\n</section>\n<section id=\"retrieve-everything-at-once-if-you-know-you-will-need-it\">\n<h2>Mengambil semuanya sekaligus jika anda mengetahui anda akan membutuhkannya<a class=\"heading-anchor\" href=\"#retrieve-everything-at-once-if-you-know-you-will-need-it\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Hitting the database multiple times for different parts of a single 'set' of\ndata that you will need all parts of is, in general, less efficient than\nretrieving it all in one query. This is particularly important if you have a\nquery that is executed in a loop, and could therefore end up doing many database\nqueries, when only one was needed. So:</p>\n<section id=\"use-queryset-select-related-and-prefetch-related\">\n<h3>Gunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.select_related()</span></code> dan <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>Memahami <a class=\"reference internal\" href=\"/id/1.10/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> dan <a class=\"reference internal\" href=\"/id/1.10/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> sepenuhnya, dan menggunakan mereka:</p>\n<ul class=\"simple\">\n<li><p>in <a class=\"reference internal\" href=\"/id/1.10/topics/db/managers/\"><span class=\"doc\">managers and default managers</span></a> where\nappropriate. Be aware when your manager is and is not used; sometimes this is\ntricky so don't make assumptions.</p></li>\n<li><p>in view code or other layers, possibly making use of\n<a class=\"reference internal\" href=\"/id/1.10/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> where needed.</p></li>\n</ul>\n</section>\n</section>\n<section id=\"don-t-retrieve-things-you-don-t-need\">\n<h2>Jangan mengambil hal yang tidak anda butuhkan<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>Gunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.values()</span></code> dan <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 just 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=\"/id/1.10/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>Gunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.defer()</span></code> dan <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=\"/id/1.10/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=\"/id/1.10/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>Also, be aware that there is some (small extra) overhead incurred inside\nDjango when constructing a model with deferred fields. Don't be too aggressive\nin deferring fields without profiling as the database has to read most of the\nnon-text, non-VARCHAR data from the disk for a single row in the results, even\nif it ends up only using a few columns. The <code class=\"docutils literal notranslate\"><span class=\"pre\">defer()</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">only()</span></code> methods\nare most useful when you can avoid loading a lot of text data or for fields\nthat might take a lot of processing to convert back to Python. As always,\nprofile first, then optimize.</p>\n</section>\n<section id=\"use-queryset-count\">\n<h3>Gunakan <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>..jika anda hanya ingin menghitung, daripada melakukan <code class=\"docutils literal notranslate\"><span class=\"pre\">len(queryset)</span></code>.</p>\n</section>\n<section id=\"use-queryset-exists\">\n<h3>Gunakan <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>...if you only want to find out if at least one result exists, rather than <code class=\"docutils literal notranslate\"><span class=\"pre\">if</span>\n<span class=\"pre\">queryset</span></code>.</p>\n<p>Tetapi:</p>\n</section>\n<section id=\"don-t-overuse-count-and-exists\">\n<span id=\"overuse-of-count-and-exists\"></span><h3>Jangan berlebihan <code class=\"docutils literal notranslate\"><span class=\"pre\">count()</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">exists()</span></code><a class=\"heading-anchor\" href=\"#don-t-overuse-count-and-exists\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>If you are going to need other data from the QuerySet, just evaluate it.</p>\n<p>For example, assuming an Email model that has a <code class=\"docutils literal notranslate\"><span class=\"pre\">body</span></code> attribute and a\nmany-to-many relation to User, the following template code is optimal:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</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=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">display_inbox</span> <span class=\"cp\">%}</span>\n  <span class=\"cp\">{%</span> <span class=\"k\">with</span> <span class=\"nv\">emails</span><span class=\"o\">=</span><span class=\"nv\">user.emails.all</span> <span class=\"cp\">%}</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">emails</span> <span class=\"cp\">%}</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>You have <span class=\"cp\">{{</span> <span class=\"nv\">emails</span><span class=\"o\">|</span><span class=\"nf\">length</span> <span class=\"cp\">}}</span> email(s)<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">email</span> <span class=\"k\">in</span> <span class=\"nv\">emails</span> <span class=\"cp\">%}</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">email.body</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">else</span> <span class=\"cp\">%}</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>No messages today.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n  <span class=\"cp\">{%</span> <span class=\"k\">endwith</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>DIa optimal karena:</p>\n<ol class=\"arabic simple\">\n<li><p>Since QuerySets are lazy, this does no database queries if 'display_inbox'\nis False.</p></li>\n<li><p>Use of <a class=\"reference internal\" href=\"/id/1.10/ref/templates/builtins/#std-templatetag-with\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">with</span></code></a> means that we store <code class=\"docutils literal notranslate\"><span class=\"pre\">user.emails.all</span></code> in a variable\nfor later use, allowing its cache to be re-used.</p></li>\n<li><p>The line <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">if</span> <span class=\"pre\">emails</span> <span class=\"pre\">%}</span></code> causes <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.__bool__()</span></code> to be called,\nwhich causes the <code class=\"docutils literal notranslate\"><span class=\"pre\">user.emails.all()</span></code> query to be run on the database, and\nat the least the first line to be turned into an ORM object. If there aren't\nany results, it will return False, otherwise True.</p></li>\n<li><p>The use of <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">emails|length</span> <span class=\"pre\">}}</span></code> calls <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.__len__()</span></code>, filling\nout the rest of the cache without doing another query.</p></li>\n<li><p>The <a class=\"reference internal\" href=\"/id/1.10/ref/templates/builtins/#std-templatetag-for\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">for</span></code></a> loop iterates over the already filled cache.</p></li>\n</ol>\n<p>In total, this code does either one or zero database queries. The only\ndeliberate optimization performed is the use of the <a class=\"reference internal\" href=\"/id/1.10/ref/templates/builtins/#std-templatetag-with\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">with</span></code></a> tag. Using\n<code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.exists()</span></code> or <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.count()</span></code> at any point would cause\nadditional queries.</p>\n</section>\n<section id=\"use-queryset-update-and-delete\">\n<h3>Gunakan <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.update()</span></code> dan <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>Rather than retrieve a load of objects, set some values, and save them\nindividual, use a bulk SQL UPDATE statement, via <a class=\"reference internal\" href=\"/id/1.10/topics/db/queries/#topics-db-queries-update\"><span class=\"std std-ref\">QuerySet.update()</span></a>. Similarly, do <a class=\"reference internal\" href=\"/id/1.10/topics/db/queries/#topics-db-queries-delete\"><span class=\"std std-ref\">bulk deletes</span></a> where possible.</p>\n<p>Note, however, that these bulk update methods cannot call the <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> or\n<code class=\"docutils literal notranslate\"><span class=\"pre\">delete()</span></code> methods of individual instances, which means that any custom\nbehavior you have added for these methods will not be executed, including\nanything driven from the normal database object <a class=\"reference internal\" href=\"/id/1.10/ref/signals/\"><span class=\"doc\">signals</span></a>.</p>\n</section>\n<section id=\"use-foreign-key-values-directly\">\n<h3>Menggunakan nilai foreign key secara langsung<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>If you only need a foreign key value, use the foreign key value that is already on\nthe object you've got, rather than getting the whole related object and taking\nits primary key. i.e. do:</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>dari pada:</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>Jangan urutkan hasil jika anda tidak peduli<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>Pengurutan tidak bebas; setiap bidang yang diurutkan adalah sebuah operai basisdata harus dilakukan. Jika sebuah model awal mengurutkan (<a class=\"reference internal\" href=\"/id/1.10/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>) dan anda tidak membutuhkannya, pindahkan dia pada <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> dengan memanggil <a class=\"reference internal\" href=\"/id/1.10/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> dengan tidak ada parameter.</p>\n<p>Menambahkan indeks ke basisdata anda mungkin membantu meningkatkan penampilan pengurutan.</p>\n</section>\n</section>\n<section id=\"insert-in-bulk\">\n<h2>Insert in bulk<a class=\"heading-anchor\" href=\"#insert-in-bulk\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>When creating objects, where possible, use the\n<a class=\"reference internal\" href=\"/id/1.10/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=\"n\">Entry</span><span class=\"p\">(</span><span class=\"n\">headline</span><span class=\"o\">=</span><span class=\"s1\">&#39;This is a test&#39;</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=\"s1\">&#39;This is only a test&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">])</span>\n</code></pre></div>\n<p>...is preferable to:</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=\"s1\">&#39;This is a test&#39;</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=\"s1\">&#39;This is only a test&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Catat bahwa ada angka dari <a class=\"reference internal\" href=\"/id/1.10/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\">caveats</span> <span class=\"pre\">to</span> <span class=\"pre\">this</span> <span class=\"pre\">method</span></code></a>, jadi pastikan dia sesuai untuk kasus digunakan anda.</p>\n<p>Ini juga berlaku pada <a class=\"reference internal\" href=\"/id/1.10/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>, demikian:</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>...is preferable to:</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>...where <code class=\"docutils literal notranslate\"><span class=\"pre\">Bands</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">Artists</span></code> have a many-to-many relationship.</p>\n</section>","rootId":"database-access-optimization","toc":[{"title":"Profil dahulu","anchor":"profile-first","children":[]},{"title":"Gunakan teknik-teknik optimalisasi DB standar","anchor":"use-standard-db-optimization-techniques","children":[]},{"title":"Memahami QuerySet","anchor":"understand-querysets","children":[{"title":"Memahami penilaian QuerySet","anchor":"understand-queryset-evaluation","children":[]},{"title":"Memahami atribut tembolok","anchor":"understand-cached-attributes","children":[]},{"title":"Gunakan etiket cetakan with","anchor":"use-the-with-template-tag","children":[]},{"title":"Gunakan iterator()","anchor":"use-iterator","children":[]}]},{"title":"Lakukan pekerjaan basisdata di basisdata daripada di Python","anchor":"do-database-work-in-the-database-rather-than-in-python","children":[{"title":"Gunakan RawSQL","anchor":"use-rawsql","children":[]},{"title":"Gunakan SQL mentah","anchor":"use-raw-sql","children":[]}]},{"title":"Mengambil obyek tersendiri menggukan sebuah unik, kolom indeks","anchor":"retrieve-individual-objects-using-a-unique-indexed-column","children":[]},{"title":"Mengambil semuanya sekaligus jika anda mengetahui anda akan membutuhkannya","anchor":"retrieve-everything-at-once-if-you-know-you-will-need-it","children":[{"title":"Gunakan QuerySet.select_related() dan prefetch_related()","anchor":"use-queryset-select-related-and-prefetch-related","children":[]}]},{"title":"Jangan mengambil hal yang tidak anda butuhkan","anchor":"don-t-retrieve-things-you-don-t-need","children":[{"title":"Gunakan QuerySet.values() dan values_list()","anchor":"use-queryset-values-and-values-list","children":[]},{"title":"Gunakan QuerySet.defer() dan only()","anchor":"use-queryset-defer-and-only","children":[]},{"title":"Gunakan QuerySet.count()","anchor":"use-queryset-count","children":[]},{"title":"Gunakan QuerySet.exists()","anchor":"use-queryset-exists","children":[]},{"title":"Jangan berlebihan count() dan exists()","anchor":"don-t-overuse-count-and-exists","children":[]},{"title":"Gunakan QuerySet.update() dan delete()","anchor":"use-queryset-update-and-delete","children":[]},{"title":"Menggunakan nilai foreign key secara langsung","anchor":"use-foreign-key-values-directly","children":[]},{"title":"Jangan urutkan hasil jika anda tidak peduli","anchor":"don-t-order-results-if-you-don-t-care","children":[]}]},{"title":"Insert in bulk","anchor":"insert-in-bulk","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Menggunakan Django","url":"/id/1.10/topics/"},{"docname":"topics/db/index","title":"Model dan basisdata","url":"/id/1.10/topics/db/"}],"prev":{"docname":"topics/db/tablespaces","title":"Tablespaces","url":"/id/1.10/topics/db/tablespaces/"},"next":{"docname":"topics/db/examples/index","title":"Contoh-contoh dari hubungan model penggunaan API","url":"/id/1.10/topics/db/examples/"},"formats":{"html":"/id/1.10/topics/db/optimization/","markdown":"/id/1.10/topics/db/optimization.md","json":"/id/1.10/topics/db/optimization.json"},"source":"https://github.com/django/django/blob/stable/1.10.x/docs/topics/db/optimization.txt","official":"https://docs.djangoproject.com/id/1.10/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","fr","ja","id","pt-br","es","el","pl"]}