質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

ページネーション

Webアプリケーションにおいて、1ページに収まらないコンテンツを、各ページへのリンクを並べてアクセスしやすくする手法をページネーションと呼びます。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

0回答

1377閲覧

Djangoでページング機能を実装したリストの表示スピードを上げたい

kwmr8416

総合スコア6

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

ページネーション

Webアプリケーションにおいて、1ページに収まらないコンテンツを、各ページへのリンクを並べてアクセスしやすくする手法をページネーションと呼びます。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

0クリップ

投稿2020/11/24 06:49

編集2020/11/24 08:49

ローカル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他

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問