データベースを処理を高速化しパフォーマンスを上げることを「indexをはる(張る)」といいます。
少量のデータでは恩恵を感じることはありませんが、1万のデータを超えるような時にその効果は絶大で、劇的なパフォーマンスの向上をもたらします。
Djangoではどのようにすればindexを張れるのかを実際のコードで紹介します。
コンテンツ
必要な知識
・SQLをある程度理解していること
・「indexをはる」を理解していること
「indexをはる」がわからない人は、「indexをはる とは」などでググって調べてください。
SQLでの書き方
SQLでindexをはるにはこのように書きます。
1 |
CREATE INDEX <index名> ON <table名> (<field名>); |
実際に値を入れたら以下のようになります。
profile(プロフィール)というテーブルにある、user_id(ユーザーID)に、ids_user_idというインデックス名をはった時を仮で想定しています。
1 |
CREATE INDEX 'ids_user_id' ON 'profile' ('user_id'); |
Djangoのmodelsのカラムにindex(インデックス)をはる方法
方法は2つあります。
以下から紹介するコードも先ほど書いたものと同様に、profile(プロフィール)というテーブルにあるuser_id(ユーザーID)にインデックスを張りたいことを想定して書いていきます。
tableのフィールドにオプションを指定追加する
1つ目の方法として、fieldのオプションにdb_index=Trueを渡します。
1 2 3 4 5 6 7 |
from django.db import models class Profile(models.Model): user_id = models.IntegerField( verbose_name='user_id', db_index=True ) |
6行目がindexを貼っているコードになります。
indexを貼りたいfield(ここではuser_id)のField引数に対して、db_index=Trueを渡します。
class Metaに指定引数
2つ目の方法としてclass Metaに記述する方法があります。
djangoの1.1まではmodelのfieldオプションに指定で書くことしかできませんでしたが、1.11以降でMeta.indexesにインデックスを表すクラスで指定できるようになりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from django.db import models class Profile(models.Model): """プロフィール """ - - - user_id = models.IntegerField( verbose_name='user_id', null=False, ) class Meta: db_table = 'profile' indexes = [ models.Index(fields=['user_id'], name='index_user_id') ] |
SQLコマンドでindexをはる場合index名が必須なことはご存知だと思いますが、class Metaに記述する場合も当然必須になります。
今回それに該当するのは、name=’index_user_id’というところになります。
ちなみにこのname=’index_user_id’を省略した場合、djangoの内部システムでmigrationファイルを生成した時に自動的に命名してくれます。
省略した時の方がユニークな、被らないindex名をdjangoが内部的に自動生成してくれます。
仮に手書きで記述してnameが被ってしまい思わぬエラーを引き起こしてしまうことも考えられますので、省略してシステムに任せる方がベターかと考えます。
ちなみにどんなnameができるのかも後で紹介します。
fieldオプションに書くパターンとclass Metaに書くパターンの違い
2つのパターンを紹介しましたが、どちらがいいのでしょうか?
djangoの1.1まではmodelのfieldオプションに指定で書くことしかできませんでしたが、1.11以降でMeta.indexesにインデックスを表すクラスで指定できるようになりました。
公式にはどちらが推奨とは書いてありませんが、例えば複数のindexをはる時は、metaに書いてある方がぱっと見でわかりやすく管理もしやすいのではないでしょうか。
マイグレーションファイルの生成
というわけで書き方を紹介しましたが、まだこれだけではmodelsに書いただけでパフォーマンスが高速化されるわけではありません。
きちんとDBに反映をさせなければなりません。
早速makemigrations(マイグレーションファイルの生成)コマンドを入力してみます。
1 |
% python manage.py makemigrations |
以下ようなファイルが生成されました。
00xx_auto_20220x0x_1500.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('sample', '00xx_profile_later'), ] operations = [ migrations.AddIndex( model_name='profile', index=models.Index(fields=['user_id'], name='profile_user_id_eac8ab_idx'), ), migrations.AlterModelTable( name='profile', table='profile', ), ] |
nameを省略した場合、name=’profile_user_id_eac8ab_idx’ というようなindex名がdjangoの内部システムで自動生成してくれました。
きちんとテーブル名とフィールド名が入っているので便利ですね。
最後に、 python manage.py migrate を実行してマイグレーションファイルを実際にデータベースに適用します。
1 |
% python manage.py migrate |
以上。
参考
https://docs.djangoproject.com/ja/4.0/ref/models/fields/#db-index
まとめ
最後に今回のまとめを書いておきます。
・fieldオプションに指定する方法と、class Metaに指定する2つの方法がある
・class Metaに指定する方が管理がしやすい
・class Metaで指定する場合、name=’index_user_id’ を省略した方がユニークなindex名を自動生成してくれるのでおすすめ
最後に
いかがでしたでしょうか。
以上が、「【Django】modelsのカラムにindex(インデックス)をはる方法」の紹介記事になります。
是非あなたのDBにもインデックスを張ってパフォーマンスの高いサイト運営を目指してください。
プログラミング学習を効率良く進めるには…
私ヒロヤンがプログラミングを始めた頃は以下のような感じでした。
そしてネットで調べていくうちに膨大な時間が過ぎていきました。
私ヒロヤンの実体験より、プログラミングを効率的に学ぶために大切なことは以下のことだと考えています。
1. いつまでもダラダラとやらないで、目標を決定して短期集中する
2. マンツーマンで、わからない箇所は直ぐに質問をして即レスをもらう
.proでは私ヒロヤンが学習してきたプログラミング経験0からのpython/django、その他webサイト・サービス開発のコースが用意されています。
カウンセリング自体は無料なので話を聞いてみるだけでもいかがでしょうか?
また以下のリンク先ではdjangoを教えてくれるスクールをまとめ紹介しています。
コメントを残す