2017-11-07 3 views
0

私のdjangoアプリケーションはdjango-rest-frameworkとMySQLを使用しています。 私のアプリをテストしましたが、ほとんどの機能は応答時間が長いです。私は何が問題なのか分からない。Python django応答時間が長いが、何が間違っているのか分からない

これは最も応答時間が長い機能の1つです。

180232 function calls (171585 primitive calls) in 1.110 seconds 

    Ordered by: internal time 
    List reduced from 757 to 151 due to restriction <0.2> 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     105 0.597 0.006 0.597 0.006 /Users/jyj/.pyenv/versions/logispot_app_env/lib/python3.6/site-packages/MySQLdb/connections.py:268(query) 
     2 0.154 0.077 0.174 0.087 /Users/jyj/.pyenv/versions/logispot_app_env/lib/python3.6/site-packages/MySQLdb/connections.py:81(__init__) 
     4 0.020 0.005 0.020 0.005 /Users/jyj/.pyenv/versions/logispot_app_env/lib/python3.6/site-packages/MySQLdb/connections.py:254(autocommit) 
8800/3582 0.010 0.000 0.828 0.000 {built-in method builtins.getattr} 
    20156 0.010 0.000 0.022 0.000 {built-in method builtins.isinstance} 
    200/100 0.009 0.000 0.886 0.009 /Users/jyj/.pyenv/versions/logispot_app_env/lib/python3.6/site-packages/rest_framework/serializers.py:479(to_representation) 
     2 0.009 0.005 0.009 0.005 {function Connection.set_character_set at 0x109b506a8} 
    6920 0.009 0.000 0.009 0.000 {built-in method builtins.hasattr} 
             .... 

この機能は、リストの最初のページです。合計カウントは1000、ページサイズは100です。各レコードは1つのテーブルに加わります。クエリに時間がかかり、Django ORMをRaw Queryに変更しましたが、時間は同じです。私はそれが60ミリ秒未満を取る必要があります考えて

 2199 function calls (2133 primitive calls) in 0.195 seconds 

    Ordered by: internal time 
    List reduced from 419 to 84 due to restriction <0.2> 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     2 0.153 0.076 0.169 0.084 /Users/jyj/.pyenv/versions/logispot_app_env/lib/python3.6/site-packages/MySQLdb/connections.py:81(__init__) 
     4 0.016 0.004 0.016 0.004 /Users/jyj/.pyenv/versions/logispot_app_env/lib/python3.6/site-packages/MySQLdb/connections.py:254(autocommit) 
     3 0.014 0.005 0.014 0.005 /Users/jyj/.pyenv/versions/logispot_app_env/lib/python3.6/site-packages/MySQLdb/connections.py:268(query) 
     2 0.008 0.004 0.008 0.004 {function Connection.set_character_set at 0x109b506a8} 

長い

でも認証チェックの応答時間(たぶん私は間違った生のクエリを使用しました)。 (たぶん私の考えが間違っている)

djangoクエリが遅すぎるか、または私のアプリに何か問題がありますか?私は問題が何かを知っている。

  • DEBUGrunserverが展開されていない、それだけでローカルsettings
  • Falseです。しかし、配備すると応答時間はほぼ同じです(より速く配備されますが、照会時間は同じです)
  • 貧弱な情報は残念です。私のウェブ開発経験はほんの半年です。もっと欲しいなら、私は試してみる。

EDIT ビューコード

class OrderListCreationAPI(generics.ListCreateAPIView): 
    permission_classes = (
     permissions.IsAuthenticatedOrReadOnly, 
     IsAdminOrClient, 
    ) 
    pagination_class = StandardListPagination 


    def get_queryset(self): 
     if self.request.method == 'GET': 
      queryset = CacheOrderList.objects.all() 
      return queryset 
     else: 
      return Order.objects.all() 

    def get_serializer_class(self): 
     if self.request.method == 'GET': 
      return CacheOrderListSerializer 
     else: 
      return OrderSerializer 

シリアライザコード

class CacheOrderListSerializer(serializers.ModelSerializer): 
    base = CacheBaseSerializer(read_only=True) 

    class Meta: 
     model = CacheOrderList 
     fields = '__all__' 

モデルコード

class CacheBase(models.Model): 
    created_time = models.DateTimeField(auto_now_add=True) 
    order = models.OneToOneField('order.Order', on_delete=models.CASCADE, related_name='cache', primary_key=True) 
    driver_user = models.ForeignKey('member.DriverUser', on_delete=models.SET_NULL, null=True) 
    client_name = models.CharField(max_length=20, null=True) 
    load_address = models.CharField(max_length=45, null=True) 
    load_company = models.CharField(max_length=20, null=True) 
    load_date = models.DateField(null=True) 
    load_time = models.CharField(max_length=30) 
    unload_address = models.CharField(max_length=45, null=True) 
    unload_company = models.CharField(max_length=20, null=True) 
    unload_date = models.DateField(null=True) 
    unload_time = models.CharField(max_length=30) 
    stop_count = models.IntegerField(default=0) 
    is_round = models.BooleanField(default=False) 
    is_mix = models.BooleanField(default=False) 
    car_ton = models.CharField(max_length=15, null=True) 
    weight = models.FloatField(null=True) 
    payment_method = models.BooleanField(default=s.ORDER_PAYMENT_METHOD_ADVANCE) 
    contract_fee = models.IntegerField(null=True) 
    driver_fee = models.IntegerField(null=True) 
    order_fee = models.IntegerField(null=True) 
    is_deleted = models.BooleanField(default=False) 


class CacheOrderList(models.Model): 
    base = models.OneToOneField(CacheBase, on_delete=models.CASCADE, related_name='order_list') 
    order_status = models.IntegerField(null=True) 
    order_created_time = models.DateTimeField(null=True) 
    car_type = models.CharField(max_length=10, null=True) 
    asignee = models.CharField(max_length=20, null=True) 
    objects = CacheManager() 

    class Meta: 
     ordering = ('-order_created_time',) 
     db_table = 'CacheOrderList' 

EDIT2 enter image description here リスト機能では、既に100個のアイテムが取得されていますが、その後、1回につき1個のアプリのクエリが再度実行されます。したがって、各クエリの費やす時間は100 *時間でした。

これはおそらく、シリアライザがページ番号が付けたレコードを使用しなかったためです。したがって、ページネーション2のクエリ+シリアライザ100のクエリ+その他。

なぜ起こったのかわかりません。

+0

あなたはどのように多くの行がありますか? mysqlで同じクエリを直接実行しようとしましたか? –

+0

約1000です。そして私はmysqlで実行します。それは60ms以下でした。私のアプリケーションで生のクエリ(同じクエリ)を使用するようにコードを変更しました。時間は私の投稿結果と同じです。 –

+0

あなたもコードを投稿できますか? –

答えて

1

基本フィールドのCacheOrderListクエリーセットでselect_relatedを使用します。これは、メソッドで提供する外部キーの関連付けを持つクエリセットキャッシュを準備します。これは、基本的に何度もDBにヒットしません。

def get_queryset(self): 
    if self.request.method == 'GET': 
     # prepare related models cache using `select_related` 
     queryset = CacheOrderList.objects.all().select_related('base') 
     return queryset 
    else: 
     return Order.objects.all() 
+0

ありがとうございます。私はこのポストを見た。 http://ses4j.github.io/2015/11/23/optimizing-slow-django-rest-framework-performance/ –

関連する問題