Djangoプロジェクト最適化データベース運用まとめ
QuerySet.explain() を使用して、 データベースが特定の QuerySet をどのように実行するかを調べます。
また、django-debug-toolbar のような外部プロジェクトや、データベースを直接監視するツールを使用するのもよいでしょう。
賢明にインデックスを作成する
インデックスはクエリの高速化に役立ちますが、インデックスにはディスクスペースが必要であり、不要なインデックスを作成すると無駄が増えるだけであることに注意してください。
<マーク
では、どのフィールドにインデックスを付ける必要があるのでしょうか?これは良い意味で不可解な質問ですが、以下のリストが参考になります。
- WHERE条件句に頻繁に登場するフィールド(Djangoではfilterでフィルタリングされるフィールドと呼ばれる)。
- グループ分けや並べ替えによく使われるフィールド
- アクセス頻度の高い複数の列に対して複合インデックスを作成するが、複合インデックスの順番は使用頻度によって決まるので注意すること
class ModelName(models.Model):
# Field is indexed using db_index
name = models.CharField(db_index=True, max_length=100)
class Meta:
# Joint unique indexes using index_together
index_together = ('field1', 'field2')
永続的なデータベース接続を設定する
SQL実行回数の削減
データベースに何度もアクセスすることは、1回のアクセスですべてを問い合わせるよりも効率が悪くなります。そのため <マーク
select_related()。SQL 接続を作成し、関連オブジェクトのフィールドを SELECT 文に含めます。 <マーク
# Standard queries
# Hits the database.
e = Entry.objects.get(id=5)
# Hits the database again to get the related Blog object.
b = e.blog
# select_related query
# Hits the database.
e = Entry.objects.select_related('blog').get(id=5)
# Doesn't hit the database, because e.blog has been prepopulated
# in the previous query.
b = e.blog
prefetch_related(): <マーク
from django.db import models
class Topping(models.Model):
name = models.CharField(max_length=30)
class Pizza(models.Model):
name = models.CharField(max_length=50)
toppings = models.ManyToManyField(Topping)
def __str__(self):
return "%s (%s)" % (
self.name,
", ".join(topping.name for topping in self.toppings.all()),
)
# good
pizza.objects.all().prefetch_related('toppings')
必須フィールドのデータのみを取得する
QuerySet.values()とvalues_list()を使用します。
QuerySet.defer()とonly()を使用します。
QuerySet.count()を使用します。
QuerySet.exists()を使用します。
count()とexists()は使い過ぎないようにしましょう。
結果をランダムにソートすることなく、一括作成、更新、削除を使用します。
一括作成。オブジェクトを作成する際には、可能な限り bulk_create() メソッドを使用し、SQL クエリの回数を減らすようにしましょう。例えば
# Good
Entry.objects.bulk_create([
Entry(headline='This is a test'),
Entry(headline='This is only a test'),
])
# Bad
Entry.objects.create(headline='This is a test')
Entry.objects.create(headline='This is only a test')
<マーク
# Good
entries[0].headline = 'This is not a test'
entries[1].headline = 'This is no longer a test'
Entry.objects.bulk_update(entries, ['headline'])
# Bad
entries[0].headline = 'This is not a test'
entries[0].save()
entries[1].headline = 'This is no longer a test'
entries[1].save()
<マーク
一括挿入。複数のオブジェクトで add() を使用すると、ManyToManyFields にオブジェクトを挿入する際の SQL クエリーの数を減らすことができます。
例
# good
my_band.members.add(me, my_friend)
# Bad
my_band.members.add(me)
my_band.members.add(my_friend)
# Good
PizzaToppingRelationship = Pizza.toppings.through
PizzaToppingRelationship.objects.bulk_create([
PizzaToppingRelationship(pizza=my_pizza, topping=pepperoni),
PizzaToppingRelationship(pizza=your_pizza, topping=pepperoni),
PizzaToppingRelationship(pizza=your_pizza, topping=mushroom),
], ignore_conflicts=True)
# Bad
my_pizza.toppings.add(pepperoni)
your_pizza.toppings.add(pepperoni, mushroom)
<マーク
一括削除 ManyToManyFields からオブジェクトを削除する場合、複数のオブジェクトで remove() を使用すると、SQL クエリの数を減らすことができます。
例えば
# Good
my_band.members.remove(me, my_friend)
# Bad
my_band.members.remove(me)
my_band.members.remove(my_friend)
# Good
from django.db.models import Q
PizzaToppingRelationship = Pizza.toppings.through
PizzaToppingRelationship.objects.filter(
Q(pizza=my_pizza, topping=pepperoni) |
Q(pizza=your_pizza, topping=pepperoni) |
Q(pizza=your_pizza, topping=mushroom)
).delete()
# Bad
my_pizza.toppings.remove(pepperoni)
your_pizza.toppings.remove(pepperoni, mushroom)
上記は、データベースの操作の詳細を最適化するためのDjangoプロジェクトの概要であり、データベースを最適化するためのDjangoプロジェクトの詳細については、スクリプトホーム他の関連記事に注意を払うください
関連
-
MySQLとRedisがデータの一貫性を確保する方法について説明します。
-
Navicat for SQLite インストールチュートリアル(インストールキット付き
-
DeepinV20 Mariadbのクイックインストールを詳しくご紹介します。
-
SQLインジェクションの実装と防止事例を解説
-
SQL実行エンジンを自作する方法
-
Navicat sqlファイルのインポートとエクスポートを素早く行う方法
-
外部キーの関連付けを行う SQL 文の完全な例
-
CentOS 8.2上のCouchDB 3.3データベースを展開する方法
-
データベースのSQLインジェクションの原理と簡単な紹介
-
SQLインジェクションについて詳しく話すいくつかの散在する知識のポイント
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン