使用 select_related prefetch_related 優(yōu)化 django rest framework 接口

哪些查詢慢谓着? 怎么查看慢在哪里猪腕? 可以參考上一遍文章

使用Django Debug Toolbar 調(diào)試 django rest framework 接口

image.png
分析  其中的sql 查詢發(fā)現(xiàn) 饺律,這個(gè)是 查詢一個(gè)表的數(shù)據(jù)后,把每條數(shù)據(jù) 都 單獨(dú)的去關(guān)聯(lián)表 查詢

select_related() prefetch_related() 官網(wǎng)文檔

相關(guān)文檔參考 :
django優(yōu)化查詢語(yǔ)句之 深入select_related與prefetch_related函數(shù)

select_related 和 prefetch_related 實(shí)現(xiàn)查詢優(yōu)化

Django ORM中的select_related和prefetch_related有什么區(qū)別?

個(gè)人 項(xiàng)目不同 铸磅,建議可以根據(jù)  Django Debug Toolbar 的分析缀遍,來(lái)確定使用  select_related和prefetch_related

一些建議:
select_related    >    OneToOneField 和ForeignKey
prefetch_related    >    ManyToManyField

例:使用 select_related 優(yōu)化 django rest framework 接口

表單關(guān)系

image.png

model 頁(yè)面

'''
可以看到 設(shè)備型號(hào) 通過(guò)  ForeignKey 關(guān)聯(lián) 廠商  設(shè)備類型 表
'''
class Manufacturers(models.Model):
    '''
    基本信息 廠商
    '''
    id = models.AutoField('id', primary_key=True, help_text="id")
    name = models.CharField("廠商名稱", max_length=50, help_text="廠商名稱(驗(yàn)證重復(fù))", unique=True)
    note = models.TextField("備注", default="", help_text="備注", null=True, blank=True)
    add_time = models.DateTimeField("添加時(shí)間", auto_now_add=True)

    class Meta:
        verbose_name = "廠商"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.id

class DeviceTypes(models.Model):
    '''
    基本信息 設(shè)備類型
    '''
    id = models.AutoField('id', primary_key=True, help_text="id")
    name = models.CharField("設(shè)備類型", max_length=50, help_text="設(shè)備類型名稱(驗(yàn)證重復(fù))", unique=True)
    note = models.TextField("備注", default="", help_text="備注", null=True, blank=True)
    add_time = models.DateTimeField("添加時(shí)間", auto_now_add=True)

    class Meta:
        verbose_name = "設(shè)備類型"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.id

class DeviceModels(models.Model):
    '''
    基本信息 設(shè)備型號(hào)
    '''
    id = models.AutoField('id', primary_key=True, help_text="id")
    name = models.CharField("設(shè)備型號(hào)名稱", max_length=100, help_text="設(shè)備型號(hào)名稱(驗(yàn)證重復(fù))", unique=True)
    manufacturers = models.ForeignKey(Manufacturers, on_delete=models.PROTECT, related_name='manufacturers_id', verbose_name="廠商id")
    devicetype = models.ForeignKey(DeviceTypes, on_delete=models.PROTECT, related_name='devicetype_id', verbose_name="設(shè)備類型id")
    price = models.IntegerField("價(jià)格", default="", help_text="價(jià)格", null=True, blank=True)
    life_cycle = models.IntegerField("生命周期", default="", help_text="生命周期", null=True, blank=True)
    templateids = models.CharField("監(jiān)控模板", max_length=255, help_text="監(jiān)控模板", null=True, blank=True)
    note = models.TextField("備注", default="", help_text="備注", null=True, blank=True)
    add_time = models.DateTimeField("添加時(shí)間", auto_now_add=True)

    class Meta:
        verbose_name = "設(shè)備型號(hào)"
        verbose_name_plural = verbose_name

Serializer 頁(yè)面

class ManufacturersSerializer(serializers.ModelSerializer):
    '''
    廠商 Serializer
    '''
    def validate(self, attrs):
        return attrs

    class Meta:
        ordering = ['-id']
        model = Manufacturers
        fields = "__all__"

class DeviceTypesSerializer(serializers.ModelSerializer):
    '''
    設(shè)備類型 Serializer
    '''
    def validate(self, attrs):
        return attrs

    class Meta:
        ordering = ['-id']
        model = DeviceTypes
        fields = "__all__"

class DeviceModelsSerializer(serializers.ModelSerializer):
    '''
    設(shè)備型號(hào) Serializer
    '''
    manufacturers = ManufacturersSerializer()
    devicetype = DeviceTypesSerializer()
    value = serializers.SerializerMethodField()
    def validate(self, attrs):
        return attrs

    class Meta:
        ordering = ['-id']
        model = DeviceModels
        fields = "__all__"

    def get_value(self, obj):
        return obj.manufacturers.name+' '+obj.devicetype.name+' '+obj.name

views.py 頁(yè)面

class DeviceModelsViewset(viewsets.ModelViewSet):
    '''
    list:
        獲取所有設(shè)備型號(hào)信息
    read:
        根據(jù)id獲取單個(gè)設(shè)備型號(hào)信息
    create:
        創(chuàng)建新的設(shè)備型號(hào)信息
    update:
        根據(jù)id更新單個(gè)設(shè)備類型信息的全部字段
    partial_update:
        根據(jù)id更新單個(gè)設(shè)備類型信息的字段
    delete:
        根據(jù)id刪除單個(gè)設(shè)備類型信息
    '''
    queryset = DeviceModels.objects.all().order_by('-id')   # 關(guān)注這行 慕匠,后面主要在這里修改
    serializer_class = DeviceModelsSerializer
    pagination_class = GenericsPageNumberPagination
queryset = DeviceModels.objects.all().order_by('-id')   # 關(guān)注這行 ,后面主要在這里修改
# 分頁(yè)查詢后域醇,一直在重復(fù)查詢  basic_devicetypes   basic_manufacturers  總共花費(fèi) 47ms
image.png
    queryset = DeviceModels.objects.select_related('manufacturers', 'devicetype').order_by('-id')  
    # 用 join 的方法 只查詢了一次 台谊,總共花費(fèi) 11ms
    SELECT `basic_devicemodels`.`id`,
       `basic_devicemodels`.`name`,
       `basic_devicemodels`.`manufacturers_id`,
       `basic_devicemodels`.`devicetype_id`,
       `basic_devicemodels`.`price`,
       `basic_devicemodels`.`life_cycle`,
       `basic_devicemodels`.`templateids`,
       `basic_devicemodels`.`note`,
       `basic_devicemodels`.`add_time`,
       `basic_manufacturers`.`id`,
       `basic_manufacturers`.`name`,
       `basic_manufacturers`.`note`,
       `basic_manufacturers`.`add_time`,
       `basic_devicetypes`.`id`,
       `basic_devicetypes`.`name`,
       `basic_devicetypes`.`note`,
       `basic_devicetypes`.`add_time`
  FROM `basic_devicemodels`
 INNER JOIN `basic_manufacturers`
    ON (`basic_devicemodels`.`manufacturers_id` = `basic_manufacturers`.`id`)
 INNER JOIN `basic_devicetypes`
    ON (`basic_devicemodels`.`devicetype_id` = `basic_devicetypes`.`id`)
 ORDER BY `basic_devicemodels`.`id` DESC
 LIMIT 10
image.png
 點(diǎn)擊 Expl 可以看下查詢的 詳細(xì)分析
image.png
queryset = DeviceModels.objects.prefetch_related('manufacturers', 'devicetype').order_by('-id')
# 分頁(yè)查詢后,再查詢  basic_devicetypes   basic_manufacturers 組合  總共花費(fèi) 11ms
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末譬挚,一起剝皮案震驚了整個(gè)濱河市锅铅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌减宣,老刑警劉巖盐须,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異漆腌,居然都是意外死亡贼邓,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門闷尿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)塑径,“玉大人,你說(shuō)我怎么就攤上這事填具⊥骋ǎ” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵劳景,是天一觀的道長(zhǎng)绑咱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)枢泰,這世上最難降的妖魔是什么描融? 我笑而不...
    開(kāi)封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮衡蚂,結(jié)果婚禮上窿克,老公的妹妹穿的比我還像新娘骏庸。我一直安慰自己,他們只是感情好年叮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布具被。 她就那樣靜靜地躺著,像睡著了一般只损。 火紅的嫁衣襯著肌膚如雪一姿。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天跃惫,我揣著相機(jī)與錄音叮叹,去河邊找鬼。 笑死爆存,一個(gè)胖子當(dāng)著我的面吹牛蛉顽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播先较,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼携冤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了闲勺?” 一聲冷哼從身側(cè)響起曾棕,我...
    開(kāi)封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎菜循,沒(méi)想到半個(gè)月后睁蕾,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡债朵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年子眶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片序芦。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡臭杰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谚中,到底是詐尸還是另有隱情渴杆,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布宪塔,位于F島的核電站磁奖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏某筐。R本人自食惡果不足惜比搭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望南誊。 院中可真熱鬧身诺,春花似錦蜜托、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至穴亏,卻和暖如春蜂挪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗓化。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工棠涮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蟆湖。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像玻粪,于是被迫代替她去往敵國(guó)和親隅津。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容