【发布时间】:2015-05-15 00:41:31
【问题描述】:
我正在为我的 API 使用 Django REST 框架,昨天我想看看它是如何处理大数据的。我找到了 this tutorial 关于如何分析您的请求(由 Tom Christie 撰写),我发现对于 10.000 个用户,我的请求花费了惊人的 2 分 20 分钟。
大部分时间都花在序列化对象上(大约 65%),所以我想知道我可以做些什么来加快速度?
我的用户模型实际上是在扩展默认的 django 模型,所以使用 .values() 不起作用,因为我也没有得到嵌套模型(即使它快很多)。
任何帮助将不胜感激:)
编辑
在检索我的查询集时,我已经在使用 .select_related(),它缩短了我的时间,但只有几秒钟。总查询数为 10,所以我的问题不在于数据库访问。
另外,我正在使用 .defer(),以避免在此请求中不需要的字段。这也提供了一个小的改进,但还不够。
编辑#2
Models
from django.contrib.auth.models import User
from django.db.models import OneToOneField
from django.db.models import ForeignKey
from userena.models import UserenaLanguageBaseProfile
from django_extensions.db.fields import CreationDateTimeField
from django_extensions.db.fields import ModificationDateTimeField
from mycompany.models import MyCompany
class UserProfile(UserenaLanguageBaseProfile):
user = OneToOneField(User, related_name='user_profile')
company = ForeignKey(MyCompany)
created = CreationDateTimeField(_('created'))
modified = ModificationDateTimeField(_('modified'))
Serializers
from django.contrib.auth.models import User
from rest_framework import serializers
from accounts.models import UserProfile
class UserSerializer(serializers.ModelSerializer):
last_login = serializers.ReadOnlyField()
date_joined = serializers.ReadOnlyField()
is_active = serializers.ReadOnlyField()
class Meta:
model = User
fields = (
'id',
'last_login',
'username',
'first_name',
'last_name',
'email',
'is_active',
'date_joined',
)
class UserProfileSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = UserProfile
fields = (
'id',
'user',
'mugshot',
'language',
)
Views
class UserProfileList(generics.GenericAPIView,
mixins.ListModelMixin,
mixins.CreateModelMixin):
serializer_class = UserProfileSerializer
permission_classes = (UserPermissions, )
def get_queryset(self):
company = self.request.user.user_profile.company
return UserProfile.objects.select_related().filter(company=company)
@etag(etag_func=UserListKeyConstructor())
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
【问题讨论】:
-
我们将需要查看您的模型和序列化程序,以了解可能出现的缓慢情况。
-
好的,所以我重新启动了我的服务器(因为它抛出了一些异常)并删除了一些不必要的字段,现在它运行得更好了(大约 32 秒)。凯文,这似乎是你可以接受的时间吗?
-
我不知道你在序列化程序中做了什么,所以这可能非常好(如果你使用
SerializerMethodField或处理数据的属性)或非常糟糕(如果你是只是从数据库中提取东西)。 -
我添加了相关代码sn-ps。不做任何数据处理,只是计算一些 ETag。我今天将重新运行测试,看看我是否有相同的时间。
标签: django django-rest-framework django-orm django-serializer