ローカルPCとAWS(APとDBが共存するインスタンス1つ)で開発を行っています。
表題の通り、一覧表示の表示スピードを上げる必要があり、どのような対応をしたらいいのか検討がつかない状況にあります。
これまでにAWSで1GB(ローカルでは100MB)のCSVファイルをインポートし一覧表示させました。
この一覧表示はページングで7項目のレコード20件を1ページとして表示させていますが、
以下のように、ブラウザで表示されるまでの時間として
t2.micro→50秒 t2.xlarge→25秒
と、スペックを上げると約半分になりましたが、かなり遅いです(時間は大体です以下同様)。
調査した内容ですが、
ORMを利用しているため、コンソール上にSQLを発行し、実行されるSQLとして以下の2つが一覧表示やページ選択した際に実行されます。
(0.063) SELECT COUNT(*) AS "__count" FROM "working_list_nippotable"; args=() (0.172) SELECT "working_list_nippotable"."id", "working_list_nippotable"."workday", "working_list_nippotable"."serialno", "working_list_nippotable"."productname", "working_list_nippotable"."productno", "working_list_nippotable"."workcontents", "working_list_nippotable"."worktypecd", "working_list_nippotable"."starttime", "working_list_nippotable"."endtime", "working_list_nippotable"."biko", "working_list_nippotable"."createday", "working_list_nippotable"."createname", "working_list_nippotable"."updatename", "working_list_nippotable"."draftflg", "working_list_nippotable"."updateflg", "working_list_nippotable"."approvalflg" FROM "working_list_nippotable" ORDER BY "working_list_nippotable"."workday" ASC, "working_list_nippotable"."starttime" ASC, "working_list_nippotable"."endtime" ASC, "working_list_nippotable"."updatename" ASC LIMIT 20 OFFSET 20; args=()
これは、最初のSELECT文のCOUNTメソッドでレコード件数を取得し、次のSELECT文で当該レコード20件分を読み込んでいます。ここでは表示項目(7項目)だけではなく全項目読み込んでおり、models.pyで記述したソートが実行されています。
ローカルでCSVファイルの読み込みが100MBまでしかできておらず環境別で比較できない状況ではありますが、1GBのデータが入ったAWS上のデータベースに上記の2つのSQL文を直接実行し結果が返ってくるまでの時間を計測しました。
t2.micro→ SELECT COUNT(*) AS "__count" FROM 対象テーブル ~:17秒 SELECT 対象項目,.... FROM 対象テーブル ~: 17秒 t2.xlarge→ SELECT COUNT(*) AS "__count" FROM 対象テーブル ~:8秒 SELECT 対象項目,.... FROM 対象テーブル ~: 1秒
この結果と冒頭の一覧表示(ブラウザで表示)にかかった時間を差し引くとSQLの実行処理とは別に15秒ほど他の処理に時間がかかっているということになります。
このようにまだ調査しかしておらずこれからどのように対応したらいいのかがわかりません。何かヒントになることまたは見落としているポイントがあれば、教えてください。
あとは、設計時点で無理があるようなことであればそちらの方向でもアイデア頂けますでしょうか。
よろしくお願いいたします。
views.py(ページ読み込みクラス)
from django.views import generic from .models import nippotable from pure_pagination.mixins import PaginationMixin class workinglistIndex(PaginationMixin, generic.ListView): model = nippotable paginate_by = 20 template_name = 'working_list/nippotable_list.html'
nippotable_list.html(ページング記述部分)
<div class="nav justify-content-center"> {% if is_paginated %} <ul class="pagination paging_size" style="margin:5%;"> {% if page_obj.has_previous %} <li><a class="page-link text-primary d-inline-block" href="?{{ page_obj.previous_page_number.querystring }}">前</a></li> {% else %} <li class="disabled"> <div class="page-link text-secondary d-inline-block disabled" href="#">前</div> </li> {% endif %} {% for link_page in page_obj.pages %} {% if link_page %} {% if link_page == page_obj.number %} <li class="disabled"> <div class="page-link text-secondary d-inline-block disabled" href="#">{{ link_page }}</div> </li> {% else %} <li><a class="page-link text-primary d-inline-block" href="?{{ link_page.querystring }}">{{ link_page }}</a> </li> {% endif %} {% else %} <li class="disabled"><a class="page-link text-secondary d-inline-block text-muted">...</a></li> {% endif %} {% endfor %} {% if page_obj.has_next %} <li><a class="page-link text-primary d-inline-block" href="?{{ page_obj.next_page_number.querystring }}">次</a> </li> {% else %} <li class="disabled"> <div class="page-link text-secondary d-inline-block disabled" href="#">次</div> </li> {% endif %} </ul> {% endif %} </div>
models.py
from django.db import models # 日報テーブル class nippotable(models.Model): #actcd = models.IntegerField('アカウントコード') /外部キー workday = models.DateField('作業日') serialno= models.CharField('製番(製造番号)', max_length=20) productname = models.CharField('製品品名(仕事名)', max_length=50) productno = models.CharField('製品NO.', max_length=3) workcontents = models.CharField('工程(業務)名', max_length=50) worktypecd = models.IntegerField('工程(業務種別)コード') starttime = models.DateTimeField('開始時間') endtime = models.DateTimeField('終了時間') biko = models.CharField('備考', max_length=50) createday = models.DateField('作成日') createname = models.CharField('更新者', max_length=20) updatename = models.CharField('作成者', max_length=20) draftflg = models.BooleanField('下書きフラグ') updateflg = models.BooleanField('更新フラグ') approvalflg = models.BooleanField('承認フラグ') class Meta: ordering = ['workday', 'starttime', 'endtime', 'updatename'] def __str__(self): return self.workday
ap:Django
db:PostgreSQL
web:Nginx(Gunicorn)
インスタンス:t2.micro他
あなたの回答
tips
プレビュー